You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2020/01/27 15:47:29 UTC
[camel] 08/10: [CAMEL-14437] Remove usage of JSonSchemaHelper in
the tooling
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 41ed1d42641fd0246324dccfe56953833f66ba15
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Sat Jan 25 15:09:33 2020 +0100
[CAMEL-14437] Remove usage of JSonSchemaHelper in the tooling
# Conflicts:
# tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/JSonSchemaHelper.java
---
components/camel-as2/camel-as2-component/pom.xml | 23 -
components/camel-salesforce/pom.xml | 26 -
components/camel-servicenow/pom.xml | 26 -
.../camel/tooling/util/JSonSchemaHelper.java | 122 --
.../apache/camel/tooling/util/PackageHelper.java | 18 +-
.../camel/tooling/util/PackageHelperTest.java | 24 +-
.../camel/maven/packaging/PrepareCatalogMojo.java | 1478 ++++++++------------
.../maven/packaging/PrepareUserGuideMojo.java | 47 +-
.../camel/maven/packaging/ValidateHelper.java | 101 +-
9 files changed, 646 insertions(+), 1219 deletions(-)
diff --git a/components/camel-as2/camel-as2-component/pom.xml b/components/camel-as2/camel-as2-component/pom.xml
index 7b2cd19..0204c6c 100644
--- a/components/camel-as2/camel-as2-component/pom.xml
+++ b/components/camel-as2/camel-as2-component/pom.xml
@@ -170,29 +170,6 @@
</executions>
</plugin>
- <!-- generate components meta-data and validate component includes documentation etc -->
- <plugin>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-package-maven-plugin</artifactId>
- <version>${project.version}</version>
- <executions>
- <execution>
- <id>prepare</id>
- <goals>
- <goal>prepare-components</goal>
- </goals>
- <phase>generate-resources</phase>
- </execution>
- <execution>
- <id>validate</id>
- <goals>
- <goal>validate-components</goal>
- </goals>
- <phase>prepare-package</phase>
- </execution>
- </executions>
- </plugin>
-
<!-- add generated source and test source to build -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
diff --git a/components/camel-salesforce/pom.xml b/components/camel-salesforce/pom.xml
index ca4648b..af8f92d 100644
--- a/components/camel-salesforce/pom.xml
+++ b/components/camel-salesforce/pom.xml
@@ -41,30 +41,4 @@
<salesforce.component.root>${project.basedir}</salesforce.component.root>
</properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-package-maven-plugin</artifactId>
- <version>${project.version}</version>
- <executions>
- <execution>
- <id>prepare</id>
- <goals>
- <goal>prepare-components</goal>
- </goals>
- <phase>generate-resources</phase>
- </execution>
- <execution>
- <id>validate</id>
- <goals>
- <goal>validate-components</goal>
- </goals>
- <phase>prepare-package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
</project>
diff --git a/components/camel-servicenow/pom.xml b/components/camel-servicenow/pom.xml
index 159835e..cbce2f6 100644
--- a/components/camel-servicenow/pom.xml
+++ b/components/camel-servicenow/pom.xml
@@ -41,30 +41,4 @@
<servicenow.component.root>${project.basedir}</servicenow.component.root>
</properties>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-package-maven-plugin</artifactId>
- <version>${project.version}</version>
- <executions>
- <execution>
- <id>prepare</id>
- <goals>
- <goal>prepare-components</goal>
- </goals>
- <phase>generate-resources</phase>
- </execution>
- <execution>
- <id>validate</id>
- <goals>
- <goal>validate-components</goal>
- </goals>
- <phase>prepare-package</phase>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
</project>
diff --git a/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/JSonSchemaHelper.java b/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/JSonSchemaHelper.java
deleted file mode 100644
index 9d04cc9..0000000
--- a/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/JSonSchemaHelper.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.util;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import org.apache.camel.util.json.JsonObject;
-import org.apache.camel.util.json.Jsoner;
-
-/**
- * A helper class for <a href="http://json-schema.org/">JSON schema</a>.
- */
-public final class JSonSchemaHelper {
-
- private JSonSchemaHelper() {
- }
-
- /**
- * Parses the json schema to split it into a list or rows, where each row contains key value pairs with the metadata
- *
- * @param group the group to parse from such as <tt>component</tt>, <tt>componentProperties</tt>, or <tt>properties</tt>.
- * @param json the json
- * @return a list of all the rows, where each row is a set of key value pairs with metadata
- */
- @SuppressWarnings("unchecked")
- public static List<Map<String, String>> parseJsonSchema(String group, String json, boolean parseProperties) {
- List<Map<String, String>> answer = new ArrayList<>();
- if (json == null) {
- return answer;
- }
-
- // convert into a List<Map<String, String>> structure which is expected as output from this parser
- try {
- JsonObject output = (JsonObject) Jsoner.deserialize(json);
- for (String key : output.keySet()) {
- Map<?, ?> row = output.getMap(key);
- if (key.equals(group)) {
- if (parseProperties) {
- // flatten each entry in the row with name as they key, and its value as the content (its a map also)
- for (Object obj : row.entrySet()) {
- Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
- Map<String, String> newRow = new LinkedHashMap<>();
- newRow.put("name", entry.getKey().toString());
-
- Map<String, String> newData = transformMap((Map<?, ?>) entry.getValue());
- newRow.putAll(newData);
- answer.add(newRow);
- }
- } else {
- // flattern each entry in the row as a list of single Map<key, value> elements
- Map<?, ?> newData = transformMap(row);
- for (Object obj : newData.entrySet()) {
- Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
- Map<String, String> newRow = new LinkedHashMap<>();
- newRow.put(entry.getKey().toString(), entry.getValue().toString());
- answer.add(newRow);
- }
- }
- }
- }
- } catch (Exception e) {
- // wrap parsing exceptions as runtime
- throw new RuntimeException("Cannot parse json", e);
- }
-
- return answer;
- }
-
- private static String escapeJson(String value) {
- // need to safe encode \r as \\r so its escaped
- // need to safe encode \n as \\n so its escaped
- // need to safe encode \t as \\t so its escaped
- return value
- .replace("\\r", "\\\\r")
- .replace("\\n", "\\\\n")
- .replace("\\t", "\\\\t");
- }
-
- private static Map<String, String> transformMap(Map<?, ?> jsonMap) {
- Map<String, String> answer = new LinkedHashMap<>();
-
- for (Object rowObj : jsonMap.entrySet()) {
- Map.Entry<?, ?> rowEntry = (Map.Entry<?, ?>) rowObj;
- // if its a list type then its an enum, and we need to parse it as a single line separated with comma
- // to be backwards compatible
- Object newValue = rowEntry.getValue();
- if (newValue instanceof List) {
- List<?> list = (List<?>) newValue;
- newValue = list.stream().map(Object::toString)
- .collect(Collectors.joining(","));
- }
- // ensure value is escaped
- String value = escapeJson(newValue.toString());
- answer.put(rowEntry.getKey().toString(), value);
- }
-
- return answer;
- }
-
-}
diff --git a/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/PackageHelper.java b/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/PackageHelper.java
index 19345dd..49c6751 100644
--- a/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/PackageHelper.java
+++ b/tooling/camel-tooling-util/src/main/java/org/apache/camel/tooling/util/PackageHelper.java
@@ -18,7 +18,6 @@ package org.apache.camel.tooling.util;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -26,7 +25,6 @@ import java.io.LineNumberReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
@@ -71,7 +69,7 @@ public final class PackageHelper {
}
public static String loadText(File file) throws IOException {
- return loadText(new FileInputStream(file));
+ return loadText(file.toPath());
}
public static String loadText(Path file) throws IOException {
@@ -112,20 +110,20 @@ public final class PackageHelper {
return answer;
}
- public static Set<File> findJsonFiles(File rootDir) {
- return findJsonFiles(rootDir, new HashSet<>());
- }
-
public static Set<File> findJsonFiles(File rootDir, Set<File> files) {
findJsonFiles(rootDir.toPath()).forEach(p -> files.add(p.toFile()));
return files;
}
public static Stream<Path> findJsonFiles(Path rootDir) {
+ return walk(rootDir)
+ .filter(p -> p.getFileName().toString().endsWith(JSON_SUFIX));
+ }
+
+ public static Stream<Path> walk(Path rootDir) {
try {
if (Files.isDirectory(rootDir)) {
- return Files.walk(rootDir)
- .filter(p -> p.getFileName().toString().endsWith(JSON_SUFIX));
+ return Files.walk(rootDir);
} else {
return Stream.empty();
}
@@ -141,7 +139,7 @@ public final class PackageHelper {
public static String asName(Path file) {
String name = file.getFileName().toString();
if (name.endsWith(JSON_SUFIX)) {
- return name.substring(0, name.length() - 5);
+ return name.substring(0, name.length() - JSON_SUFIX.length());
}
return name;
}
diff --git a/tooling/camel-tooling-util/src/test/java/org/apache/camel/tooling/util/PackageHelperTest.java b/tooling/camel-tooling-util/src/test/java/org/apache/camel/tooling/util/PackageHelperTest.java
index 24c3e3a..f4dd40f 100644
--- a/tooling/camel-tooling-util/src/test/java/org/apache/camel/tooling/util/PackageHelperTest.java
+++ b/tooling/camel-tooling-util/src/test/java/org/apache/camel/tooling/util/PackageHelperTest.java
@@ -17,6 +17,9 @@
package org.apache.camel.tooling.util;
import java.io.File;
+import java.nio.file.Path;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -32,23 +35,26 @@ public class PackageHelperTest {
@Test
public void testFileToString() throws Exception {
- assertEquals("dk19i21)@+#(OR\n", PackageHelper.loadText(ResourceUtils.getResourceAsFile("filecontent/a.txt")));
+ File file = ResourceUtils.getResourceAsFile("filecontent/a.txt");
+ assertEquals("dk19i21)@+#(OR\n", PackageHelper.loadText(file));
}
@Test
public void testFindJsonFiles() throws Exception {
- Set<File> jsons = PackageHelper.findJsonFiles(ResourceUtils.getResourceAsFile("json"));
- Map<String, File> jsonFiles = jsons.stream().collect(Collectors.toMap(
- file -> file.getName().replace(JSON_SUFIX, ""), file -> file));
-
- assertTrue(jsonFiles.containsKey("a"), "Files a.json must be found");
- assertTrue(jsonFiles.containsKey("b"), "Files b.json must be found");
- assertFalse(jsonFiles.containsKey("c"), "File c.txt must not be found");
+ Path dir = ResourceUtils.getResourceAsFile("json").toPath();
+ List<String> jsonFiles = PackageHelper.findJsonFiles(dir)
+ .map(PackageHelper::asName)
+ .collect(Collectors.toList());
+
+ assertTrue(jsonFiles.contains("a"), "Files a.json must be found");
+ assertTrue(jsonFiles.contains("b"), "Files b.json must be found");
+ assertFalse(jsonFiles.contains("c"), "File c.txt must not be found");
}
@Test
public void testGetSchemaKind() throws Exception {
- String json = PackageHelper.loadText(ResourceUtils.getResourceAsFile("json/aop.json"));
+ File file = ResourceUtils.getResourceAsFile("json/aop.json");
+ String json = PackageHelper.loadText(file);
assertEquals("model", PackageHelper.getSchemaKind(json));
}
}
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 53d0e54..acf27b7 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
@@ -16,30 +16,40 @@
*/
package org.apache.camel.maven.packaging;
+import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileFilter;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.charset.Charset;
+import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
-import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.regex.Matcher;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
import java.util.regex.Pattern;
-
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.camel.tooling.model.BaseModel;
+import org.apache.camel.tooling.model.BaseOptionModel;
+import org.apache.camel.tooling.model.ComponentModel;
+import org.apache.camel.tooling.model.DataFormatModel;
+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.util.FileUtil;
-import org.apache.camel.tooling.util.JSonSchemaHelper;
import org.apache.camel.tooling.util.PackageHelper;
-import org.apache.commons.io.FileUtils;
+import org.apache.camel.tooling.util.Strings;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
@@ -50,6 +60,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.asciidoctor.Asciidoctor;
import org.asciidoctor.OptionsBuilder;
+import org.jruby.RubyString;
/**
* Prepares the camel catalog to include component, data format, and eip
@@ -150,6 +161,12 @@ public class PrepareCatalogMojo extends AbstractMojo {
protected File baseDir;
/**
+ * The camel-jaxp directory
+ */
+ @Parameter(defaultValue = "${project.build.directory}/../../../core/camel-jaxp")
+ protected File jaxpDir;
+
+ /**
* The directory where the camel-spring XML models are
*/
@Parameter(defaultValue = "${project.build.directory}/../../../components/camel-spring")
@@ -185,6 +202,10 @@ public class PrepareCatalogMojo extends AbstractMojo {
@Component
private MavenProjectHelper projectHelper;
+ Collection<Path> allJsonFiles;
+ Collection<Path> allPropertiesFiles;
+ Map<Path, BaseModel<?>> allModels;
+
/**
* Execute goal.
*
@@ -195,305 +216,226 @@ public class PrepareCatalogMojo extends AbstractMojo {
*/
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
- executeModel();
- Set<String> components = executeComponents();
- Set<String> dataformats = executeDataFormats();
- Set<String> languages = executeLanguages();
- Set<String> others = executeOthers();
- executeDocuments(components, dataformats, languages, others);
- executeArchetypes();
- executeXmlSchemas();
- executeMain();
+ try {
+ allJsonFiles = new TreeSet<>();
+ allPropertiesFiles = new TreeSet<>();
+
+ Stream.concat(list(componentsDir.toPath()),
+ Stream.of(coreDir.toPath(), baseDir.toPath(), jaxpDir.toPath(), springDir.toPath()))
+ .filter(dir -> !"target".equals(dir.getFileName().toString()))
+ .map(this::getComponentPath)
+ .filter(dir -> Files.isDirectory(dir.resolve("src")))
+ .map(p -> p.resolve("target/classes"))
+ .flatMap(PackageHelper::walk)
+ .forEach(p -> {
+ String f = p.getFileName().toString();
+ if (f.endsWith(PackageHelper.JSON_SUFIX)) {
+ allJsonFiles.add(p);
+ } else if (f.equals("component.properties")
+ || f.equals("dataformat.properties")
+ || f.equals("language.properties")
+ || f.equals("other.properties")) {
+ allPropertiesFiles.add(p);
+ }
+ });
+ allModels = allJsonFiles.stream().collect(Collectors.toMap(
+ p -> p, JsonMapper::generateModel));
+
+ executeModel();
+ Set<String> components = executeComponents();
+ Set<String> dataformats = executeDataFormats();
+ Set<String> languages = executeLanguages();
+ Set<String> others = executeOthers();
+ executeDocuments(components, dataformats, languages, others);
+ executeArchetypes();
+ executeXmlSchemas();
+ executeMain();
+ } catch (Exception e) {
+ throw new MojoFailureException("Error preparing catalog", e);
+ }
}
- protected void executeModel() throws MojoExecutionException, MojoFailureException {
+ protected void executeModel() throws Exception {
+ Path coreDir = this.coreDir.toPath();
+ Path springDir = this.springDir.toPath();
+ Path modelsOutDir = this.modelsOutDir.toPath();
+
getLog().info("================================================================================");
getLog().info("Copying all Camel model json descriptors");
// lets use sorted set/maps
- Set<File> jsonFiles = new TreeSet<>();
- Set<File> duplicateJsonFiles = new TreeSet<>();
- Set<File> missingLabels = new TreeSet<>();
- Set<File> missingJavaDoc = new TreeSet<>();
+ Set<Path> jsonFiles;
+ Set<Path> duplicateJsonFiles;
+ Set<Path> missingLabels = new TreeSet<>();
+ Set<Path> missingJavaDoc = new TreeSet<>();
Map<String, Set<String>> usedLabels = new TreeMap<>();
- // find all json files in camel-core
- if (coreDir != null && coreDir.isDirectory()) {
- File target = new File(coreDir, "target/classes/org/apache/camel/model");
- PackageHelper.findJsonFiles(target, jsonFiles);
- }
-
- // find all json files in camel-spring
- if (springDir != null && springDir.isDirectory()) {
- File target = new File(springDir, "target/classes/org/apache/camel/spring");
- PackageHelper.findJsonFiles(target, jsonFiles);
- File target2 = new File(springDir, "target/classes/org/apache/camel/core/xml");
- PackageHelper.findJsonFiles(target2, jsonFiles);
- }
-
+ // find all json files in camel-core and camel-spring
+ Path coreDirTarget = coreDir.resolve("target/classes/org/apache/camel/model");
+ Path springTarget1 = springDir.resolve("target/classes/org/apache/camel/spring");
+ Path springTarget2 = springDir.resolve("target/classes/org/apache/camel/core/xml");
+ jsonFiles = allJsonFiles.stream()
+ .filter(p -> p.startsWith(coreDirTarget) || p.startsWith(springTarget1) || p.startsWith(springTarget2))
+ .collect(Collectors.toCollection(TreeSet::new));
getLog().info("Found " + jsonFiles.size() + " model json files");
// make sure to create out dir
- modelsOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = modelsOutDir.list() == null || modelsOutDir.list().length == 0;
-
- for (File file : jsonFiles) {
- File to = new File(modelsOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateJsonFiles.add(to);
- getLog().warn("Duplicate model name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
+ Files.createDirectories(modelsOutDir);
+
+ duplicateJsonFiles = getDuplicates(jsonFiles);
+
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> modelsOutDir.resolve(p.getFileName()));
+ list(modelsOutDir)
+ .filter(p -> !newJsons.containsValue(p))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
+
+ for (Path file : jsonFiles) {
+ // check if we have a label as we want the eip to include labels
+ EipModel model = (EipModel) allModels.get(file);
+
+ String name = asComponentName(file);
+
+ // grab the label, and remember it in the used labels
+ String label = model.getLabel();
+ if (Strings.isNullOrEmpty(label)) {
+ missingLabels.add(file);
+ } else {
+ String[] labels = label.split(",");
+ for (String s : labels) {
+ usedLabels.computeIfAbsent(s, k -> new TreeSet<>()).add(name);
}
}
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
-
- try {
- // check if we have a label as we want the eip to include labels
- String text = PackageHelper.loadText(file);
- // just do a basic label check
- if (text.contains("\"label\": \"\"")) {
- missingLabels.add(file);
- } else {
- String name = asComponentName(file);
- Matcher matcher = LABEL_PATTERN.matcher(text);
- // grab the label, and remember it in the used labels
- if (matcher.find()) {
- String label = matcher.group(1);
- String[] labels = label.split(",");
- for (String s : labels) {
- usedLabels.computeIfAbsent(s, k -> new TreeSet<>()).add(name);
- }
- }
- }
- // check all the properties if they have description
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("properties", text, true);
- for (Map<String, String> row : rows) {
- String name = row.get("name");
- // skip checking these as they have no documentation
- if ("outputs".equals(name) || "transforms".equals(name)) {
- continue;
- }
-
- String doc = row.get("description");
- if (doc == null || doc.isEmpty()) {
- missingJavaDoc.add(file);
- break;
- }
- }
- } catch (IOException e) {
- // ignore
+ // check all the properties if they have description
+ if (model.getOptions().stream()
+ .filter(option -> !"outputs".equals(option.getName()) && !"transforms".equals(option.getName()))
+ .map(BaseOptionModel::getDescription)
+ .anyMatch(Strings::isNullOrEmpty)) {
+ missingJavaDoc.add(file);
}
}
- File all = new File(modelsOutDir, "../models.properties");
- try {
- FileOutputStream fos = new FileOutputStream(all, false);
-
- String[] names = modelsOutDir.list();
- List<String> models = new ArrayList<>();
- // sort the names
- for (String name : names) {
- if (name.endsWith(PackageHelper.JSON_SUFIX)) {
- // strip out .json from the name
- String modelName = name.substring(0, name.length() - 5);
- models.add(modelName);
- }
- }
+ Path all = modelsOutDir.resolve("../models.properties");
+ Set<String> modelNames = jsonFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", modelNames) + "\n");
- Collections.sort(models);
- for (String name : models) {
- fos.write(name.getBytes());
- fos.write("\n".getBytes());
- }
-
- fos.close();
-
- } catch (IOException e) {
- throw new MojoFailureException("Error writing to file " + all);
- }
-
- printModelsReport(jsonFiles, duplicateJsonFiles, missingLabels, usedLabels, missingJavaDoc);
+ printModelsReport(
+ jsonFiles,
+ duplicateJsonFiles,
+ missingLabels,
+ usedLabels,
+ missingJavaDoc);
}
// CHECKSTYLE:OFF
- protected Set<String> executeComponents() throws MojoExecutionException, MojoFailureException {
+ protected Set<String> executeComponents() throws Exception {
+ Path coreDir = this.coreDir.toPath();
+ Path componentsDir = this.componentsDir.toPath();
+ Path componentsOutDir = this.componentsOutDir.toPath();
+
getLog().info("Copying all Camel component json descriptors");
// lets use sorted set/maps
- Set<File> jsonFiles = new TreeSet<>();
- Set<File> duplicateJsonFiles = new TreeSet<>();
- Set<File> componentFiles = new TreeSet<>();
- Set<File> missingComponents = new TreeSet<>();
+ Set<Path> jsonFiles;
+ Set<Path> duplicateJsonFiles;
+ Set<Path> componentFiles;
+ Set<Path> missingComponents = new TreeSet<>();
Map<String, Set<String>> usedComponentLabels = new TreeMap<>();
Set<String> usedOptionLabels = new TreeSet<>();
Set<String> unlabeledOptions = new TreeSet<>();
- Set<File> missingFirstVersions = new TreeSet<>();
+ Set<Path> missingFirstVersions = new TreeSet<>();
// find all json files in components and camel-core
- if (componentsDir != null && componentsDir.isDirectory()) {
- File[] components = componentsDir.listFiles();
- if (components != null) {
- for (File dir : components) {
- if (dir.isDirectory() && !"target".equals(dir.getName())) {
- File target = new File(dir, "target/classes");
-
- // special for these as they are in sub dir
- if ("camel-as2".equals(dir.getName())) {
- target = new File(dir, "camel-as2-component/target/classes");
- } else if ("camel-salesforce".equals(dir.getName())) {
- target = new File(dir, "camel-salesforce-component/target/classes");
- } else if ("camel-olingo2".equals(dir.getName())) {
- target = new File(dir, "camel-olingo2-component/target/classes");
- } else if ("camel-olingo4".equals(dir.getName())) {
- target = new File(dir, "camel-olingo4-component/target/classes");
- } else if ("camel-box".equals(dir.getName())) {
- target = new File(dir, "camel-box-component/target/classes");
- } else if ("camel-servicenow".equals(dir.getName())) {
- target = new File(dir, "camel-servicenow-component/target/classes");
- } else if ("camel-fhir".equals(dir.getName())) {
- target = new File(dir, "camel-fhir-component/target/classes");
- } else {
- // this module must be active with a source folder
- File src = new File(dir, "src");
- boolean active = src.isDirectory() && src.exists();
- if (!active) {
- continue;
- }
- }
-
- int before = componentFiles.size();
- int before2 = jsonFiles.size();
-
- findComponentFilesRecursive(target, jsonFiles, componentFiles, new CamelComponentsFileFilter());
-
- int after = componentFiles.size();
- int after2 = jsonFiles.size();
- if (before != after && before2 == after2) {
- missingComponents.add(dir);
- }
+ componentFiles = allPropertiesFiles.stream()
+ .filter(p -> p.endsWith("component.properties"))
+ .collect(Collectors.toCollection(TreeSet::new));
+ jsonFiles = allJsonFiles.stream()
+ .filter(p -> allModels.get(p) instanceof ComponentModel)
+ .collect(Collectors.toCollection(TreeSet::new));
+ componentFiles.stream()
+ .filter(p -> p.endsWith("component.properties"))
+ .forEach(p -> {
+ Path parent = getModule(p);
+ List<Path> jsons = jsonFiles.stream()
+ .filter(f -> f.startsWith(parent))
+ .collect(Collectors.toList());
+ if (jsons.isEmpty()) {
+ missingComponents.add(parent);
}
- }
- }
- }
- if (coreDir != null && coreDir.isDirectory()) {
- File target = new File(coreDir, "target/classes");
-
- int before = componentFiles.size();
- int before2 = jsonFiles.size();
-
- findComponentFilesRecursive(target, jsonFiles, componentFiles, new CamelComponentsFileFilter());
-
- int after = componentFiles.size();
- int after2 = jsonFiles.size();
- if (before != after && before2 == after2) {
- missingComponents.add(coreDir);
- }
- }
+ });
getLog().info("Found " + componentFiles.size() + " component.properties files");
getLog().info("Found " + jsonFiles.size() + " component json files");
// make sure to create out dir
- componentsOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = componentsOutDir.list() == null || componentsOutDir.list().length == 0;
+ Files.createDirectories(componentsOutDir);
- Set<String> alternativeSchemes = new HashSet<>();
+ // Check duplicates
+ duplicateJsonFiles = getDuplicates(jsonFiles);
- for (File file : jsonFiles) {
- File to = new File(componentsOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateJsonFiles.add(to);
- getLog().warn("Duplicate component name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
- }
- }
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> componentsOutDir.resolve(p.getFileName()));
+ list(componentsOutDir)
+ .filter(p -> !newJsons.containsValue(p))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
+ Set<String> alternativeSchemes = new HashSet<>();
+
+ for (Path file : jsonFiles) {
// check if we have a component label as we want the components to
// include labels
try {
String text = PackageHelper.loadText(file);
+ ComponentModel model = JsonMapper.generateComponentModel(text);
+
String name = asComponentName(file);
- Matcher matcher = LABEL_PATTERN.matcher(text);
+
// grab the label, and remember it in the used labels
- if (matcher.find()) {
- String label = matcher.group(1);
- String[] labels = label.split(",");
- for (String s : labels) {
- Set<String> components = usedComponentLabels.computeIfAbsent(s, k -> new TreeSet<>());
- components.add(name);
- }
+ String label = model.getLabel();
+ String[] labels = label.split(",");
+ for (String s : labels) {
+ Set<String> components = usedComponentLabels.computeIfAbsent(s, k -> new TreeSet<>());
+ components.add(name);
}
- // check all the component options and grab the label(s) they
- // use
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("componentProperties", text, true);
- for (Map<String, String> row : rows) {
- String label = row.get("label");
-
- if (label != null && !label.isEmpty()) {
- String[] parts = label.split(",");
- Collections.addAll(usedOptionLabels, parts);
- }
- }
+ // check all the component options and grab the label(s) they use
+ model.getComponentOptions().stream()
+ .map(BaseOptionModel::getLabel)
+ .filter(l -> !Strings.isNullOrEmpty(l))
+ .flatMap(l -> Stream.of(label.split(",")))
+ .forEach(usedOptionLabels::add);
// check all the endpoint options and grab the label(s) they use
- int unused = 0;
- rows = JSonSchemaHelper.parseJsonSchema("properties", text, true);
- for (Map<String, String> row : rows) {
- String label = row.get("label");
- if (label != null && !label.isEmpty()) {
- String[] parts = label.split(",");
- usedOptionLabels.addAll(Arrays.asList(parts));
- } else {
- unused++;
- }
- }
-
+ model.getEndpointOptions().stream()
+ .map(BaseOptionModel::getLabel)
+ .filter(l -> !Strings.isNullOrEmpty(l))
+ .flatMap(l -> Stream.of(label.split(",")))
+ .forEach(usedOptionLabels::add);
+
+ long unused = model.getEndpointOptions().stream()
+ .map(BaseOptionModel::getLabel)
+ .filter(Strings::isNullOrEmpty)
+ .count();
if (unused >= UNUSED_LABELS_WARN) {
unlabeledOptions.add(name);
}
// remember alternative schemes
- rows = JSonSchemaHelper.parseJsonSchema("component", text, false);
- for (Map<String, String> row : rows) {
- String alternativeScheme = row.get("alternativeSchemes");
- if (alternativeScheme != null && !alternativeScheme.isEmpty()) {
- String[] parts = alternativeScheme.split(",");
- // skip first as that is the regular scheme
- alternativeSchemes.addAll(Arrays.asList(parts).subList(1, parts.length));
- }
+ String alternativeScheme = model.getAlternativeSchemes();
+ if (!Strings.isNullOrEmpty(alternativeScheme)) {
+ String[] parts = alternativeScheme.split(",");
+ // skip first as that is the regular scheme
+ alternativeSchemes.addAll(Arrays.asList(parts).subList(1, parts.length));
}
// detect missing first version
- String firstVersion = null;
- for (Map<String, String> row : rows) {
- if (row.get("firstVersion") != null) {
- firstVersion = row.get("firstVersion");
- }
- }
- if (firstVersion == null) {
+ String firstVersion = model.getFirstVersion();
+ if (Strings.isNullOrEmpty(firstVersion)) {
missingFirstVersions.add(file);
}
@@ -502,460 +444,313 @@ public class PrepareCatalogMojo extends AbstractMojo {
}
}
- Set<String> componentNames = generateJsonList(componentsOutDir.toPath(), "../components.properties");
+ Path all = componentsOutDir.resolve("../models.properties");
+ Set<String> componentNames = jsonFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", componentNames) + "\n");
- printComponentsReport(jsonFiles, duplicateJsonFiles, missingComponents, usedComponentLabels, usedOptionLabels, unlabeledOptions, missingFirstVersions);
+ printComponentsReport(
+ jsonFiles,
+ duplicateJsonFiles,
+ missingComponents,
+ usedComponentLabels,
+ usedOptionLabels,
+ unlabeledOptions,
+ missingFirstVersions);
- // filter out duplicate component names that are alternative scheme
- // names
+ // filter out duplicate component names that are alternative scheme names
componentNames.removeAll(alternativeSchemes);
return componentNames;
}
- // CHECKSTYLE:ON
- protected Set<String> executeDataFormats() throws MojoExecutionException, MojoFailureException {
+ protected Set<String> executeDataFormats() throws Exception {
+ Path dataFormatsOutDir = this.dataFormatsOutDir.toPath();
+
getLog().info("Copying all Camel dataformat json descriptors");
// lets use sorted set/maps
- Set<File> jsonFiles = new TreeSet<>();
- Set<File> duplicateJsonFiles = new TreeSet<>();
- Set<File> dataFormatFiles = new TreeSet<>();
+ Set<Path> jsonFiles;
+ Set<Path> duplicateJsonFiles;
+ Set<Path> dataFormatFiles;
Map<String, Set<String>> usedLabels = new TreeMap<>();
- Set<File> missingFirstVersions = new TreeSet<>();
+ Set<Path> missingFirstVersions = new TreeSet<>();
// find all data formats from the components directory
- if (componentsDir != null && componentsDir.isDirectory()) {
- File[] dataFormats = componentsDir.listFiles();
- if (dataFormats != null) {
- for (File dir : dataFormats) {
- // special for this as the data format is in the sub dir
- if (dir.isDirectory() && "camel-fhir".equals(dir.getName())) {
- dir = new File(dir, "camel-fhir-component");
- }
- if (dir.isDirectory() && !"target".equals(dir.getName())) {
- File target = new File(dir, "target/classes");
- // this module must be active with a source folder
- File src = new File(dir, "src");
- boolean active = src.isDirectory() && src.exists();
- if (active) {
- findDataFormatFilesRecursive(target, jsonFiles, dataFormatFiles, new CamelDataFormatsFileFilter());
- }
- }
- }
- }
- }
- if (coreDir != null && coreDir.isDirectory()) {
- File target = new File(coreDir, "target/classes");
- findDataFormatFilesRecursive(target, jsonFiles, dataFormatFiles, new CamelDataFormatsFileFilter());
- }
+ dataFormatFiles = allPropertiesFiles.stream()
+ .filter(p -> p.endsWith("dataformat.properties"))
+ .collect(Collectors.toCollection(TreeSet::new));
+ jsonFiles = allJsonFiles.stream()
+ .filter(p -> allModels.get(p) instanceof DataFormatModel)
+ .collect(Collectors.toCollection(TreeSet::new));
getLog().info("Found " + dataFormatFiles.size() + " dataformat.properties files");
getLog().info("Found " + jsonFiles.size() + " dataformat json files");
// make sure to create out dir
- dataFormatsOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = dataFormatsOutDir.list() == null || dataFormatsOutDir.list().length == 0;
-
- for (File file : jsonFiles) {
- File to = new File(dataFormatsOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateJsonFiles.add(to);
- getLog().warn("Duplicate dataformat name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
- }
- }
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
+ Files.createDirectories(dataFormatsOutDir);
- // check if we have a label as we want the data format to include
- // labels
- try {
- String text = PackageHelper.loadText(file);
- String name = asComponentName(file);
- Matcher matcher = LABEL_PATTERN.matcher(text);
- // grab the label, and remember it in the used labels
- if (matcher.find()) {
- String label = matcher.group(1);
- String[] labels = label.split(",");
- for (String s : labels) {
- Set<String> dataFormats = usedLabels.computeIfAbsent(s, k -> new TreeSet<>());
- dataFormats.add(name);
- }
- }
+ // Check duplicates
+ duplicateJsonFiles = getDuplicates(jsonFiles);
- // detect missing first version
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("dataformat", text, false);
- String firstVersion = null;
- for (Map<String, String> row : rows) {
- if (row.get("firstVersion") != null) {
- firstVersion = row.get("firstVersion");
- }
- }
- if (firstVersion == null) {
- missingFirstVersions.add(file);
- }
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> dataFormatsOutDir.resolve(p.getFileName()));
+ list(dataFormatsOutDir)
+ .filter(p -> !newJsons.containsValue(p))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
- } catch (IOException e) {
- // ignore
+ for (Path file : jsonFiles) {
+
+ DataFormatModel model = (DataFormatModel) allModels.get(file);
+
+ // Check labels
+ String name = asComponentName(file);
+ for (String s : model.getLabel().split(",")) {
+ usedLabels.computeIfAbsent(s, k -> new TreeSet<>()).add(name);
+ }
+
+ // detect missing first version
+ String firstVersion = model.getFirstVersion();
+ if (Strings.isNullOrEmpty(firstVersion)) {
+ missingFirstVersions.add(file);
}
}
- Set<String> answer = generateJsonList(dataFormatsOutDir.toPath(), "../dataformats.properties");
+ Path all = dataFormatsOutDir.resolve("../dataformats.properties");
+ Set<String> dataFormatNames = jsonFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", dataFormatNames) + "\n");
printDataFormatsReport(jsonFiles, duplicateJsonFiles, usedLabels, missingFirstVersions);
- return answer;
+ return dataFormatNames;
}
- protected Set<String> executeLanguages() throws MojoExecutionException, MojoFailureException {
+ protected Set<String> executeLanguages() throws Exception {
+ Path languagesOutDir = this.languagesOutDir.toPath();
+
getLog().info("Copying all Camel language json descriptors");
// lets use sorted set/maps
- Set<File> jsonFiles = new TreeSet<>();
- Set<File> duplicateJsonFiles = new TreeSet<>();
- Set<File> languageFiles = new TreeSet<>();
+ Set<Path> jsonFiles;
+ Set<Path> duplicateJsonFiles;
+ Set<Path> languageFiles;
Map<String, Set<String>> usedLabels = new TreeMap<>();
- Set<File> missingFirstVersions = new TreeSet<>();
+ Set<Path> missingFirstVersions = new TreeSet<>();
// find all languages from the components directory
- if (componentsDir != null && componentsDir.isDirectory()) {
- File[] languages = componentsDir.listFiles();
- if (languages != null) {
- for (File dir : languages) {
- if (dir.isDirectory() && !"target".equals(dir.getName())) {
- File target = new File(dir, "target/classes");
- // this module must be active with a source folder
- File src = new File(dir, "src");
- boolean active = src.isDirectory() && src.exists();
- if (active) {
- findLanguageFilesRecursive(target, jsonFiles, languageFiles, new CamelLanguagesFileFilter());
- }
- }
- }
- }
- }
- if (baseDir != null && baseDir.isDirectory()) {
- File target = new File(baseDir, "target/classes");
- findLanguageFilesRecursive(target, jsonFiles, languageFiles, new CamelLanguagesFileFilter());
- // also look in camel-jaxp
- target = new File(baseDir, "../camel-jaxp/target/classes");
- findLanguageFilesRecursive(target, jsonFiles, languageFiles, new CamelLanguagesFileFilter());
- }
+ languageFiles = allPropertiesFiles.stream()
+ .filter(p -> p.endsWith("language.properties"))
+ .collect(Collectors.toCollection(TreeSet::new));
+ jsonFiles = allJsonFiles.stream()
+ .filter(p -> allModels.get(p) instanceof LanguageModel)
+ .collect(Collectors.toCollection(TreeSet::new));
getLog().info("Found " + languageFiles.size() + " language.properties files");
getLog().info("Found " + jsonFiles.size() + " language json files");
// make sure to create out dir
- languagesOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = languagesOutDir.list() == null || languagesOutDir.list().length == 0;
-
- for (File file : jsonFiles) {
- File to = new File(languagesOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateJsonFiles.add(to);
- getLog().warn("Duplicate language name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
- }
- }
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
+ Files.createDirectories(languagesOutDir);
- // check if we have a label as we want the data format to include
- // labels
- try {
- String text = PackageHelper.loadText(file);
- String name = asComponentName(file);
- Matcher matcher = LABEL_PATTERN.matcher(text);
- // grab the label, and remember it in the used labels
- if (matcher.find()) {
- String label = matcher.group(1);
- String[] labels = label.split(",");
- for (String s : labels) {
- Set<String> languages = usedLabels.computeIfAbsent(s, k -> new TreeSet<>());
- languages.add(name);
- }
- }
+ // Check duplicates
+ duplicateJsonFiles = getDuplicates(jsonFiles);
- // detect missing first version
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("language", text, false);
- String firstVersion = null;
- for (Map<String, String> row : rows) {
- if (row.get("firstVersion") != null) {
- firstVersion = row.get("firstVersion");
- }
- }
- if (firstVersion == null) {
- missingFirstVersions.add(file);
- }
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> languagesOutDir.resolve(p.getFileName()));
+ list(languagesOutDir)
+ .filter(p -> !newJsons.containsValue(p))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
- } catch (IOException e) {
- // ignore
+ for (Path file : jsonFiles) {
+
+ LanguageModel model = (LanguageModel) allModels.get(file);
+
+ // Check labels
+ String name = asComponentName(file);
+ for (String s : model.getLabel().split(",")) {
+ usedLabels.computeIfAbsent(s, k -> new TreeSet<>()).add(name);
+ }
+
+ // detect missing first version
+ String firstVersion = model.getFirstVersion();
+ if (Strings.isNullOrEmpty(firstVersion)) {
+ missingFirstVersions.add(file);
}
}
- Set<String> answer = generateJsonList(languagesOutDir.toPath(), "../languages.properties");
+ Path all = languagesOutDir.resolve("../dataformats.properties");
+ Set<String> languagesNames = jsonFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", languagesNames) + "\n");
printLanguagesReport(jsonFiles, duplicateJsonFiles, usedLabels, missingFirstVersions);
- return answer;
+ return languagesNames;
}
- private Set<String> executeOthers() throws MojoFailureException {
+ private Set<String> executeOthers() throws Exception {
+ Path othersOutDir = this.othersOutDir.toPath();
+
getLog().info("Copying all Camel other json descriptors");
// lets use sorted set/maps
- Set<File> jsonFiles = new TreeSet<>();
- Set<File> duplicateJsonFiles = new TreeSet<>();
- Set<File> otherFiles = new TreeSet<>();
+ Set<Path> jsonFiles;
+ Set<Path> duplicateJsonFiles;
+ Set<Path> otherFiles;
Map<String, Set<String>> usedLabels = new TreeMap<>();
- Set<File> missingFirstVersions = new TreeSet<>();
-
- // find all others from the components directory
- if (componentsDir != null && componentsDir.isDirectory()) {
- File[] others = componentsDir.listFiles();
- if (others != null) {
- for (File dir : others) {
-
- // skip these special cases
- boolean special = "camel-core-osgi".equals(dir.getName()) || "camel-core-xml".equals(dir.getName()) || "camel-box".equals(dir.getName())
- || "camel-http-base".equals(dir.getName()) || "camel-http-common".equals(dir.getName()) || "camel-jetty-common".equals(dir.getName());
- boolean special2 = "camel-as2".equals(dir.getName()) || "camel-olingo2".equals(dir.getName()) || "camel-olingo4".equals(dir.getName())
- || "camel-servicenow".equals(dir.getName()) || "camel-salesforce".equals(dir.getName()) || "camel-fhir".equals(dir.getName());
- boolean special3 = "camel-debezium-common".equals(dir.getName());
- if (special || special2 || special3) {
- continue;
- }
-
- if (dir.isDirectory() && !"target".equals(dir.getName())) {
- File target = new File(dir, "target/classes");
- if (target.exists()) {
- // this module must be active with a source folder
- File src = new File(dir, "src");
- boolean active = src.isDirectory() && src.exists();
- if (active) {
- findOtherFilesRecursive(target, jsonFiles, otherFiles, new CamelOthersFileFilter());
- }
- }
+ Set<Path> missingFirstVersions = new TreeSet<>();
+
+ otherFiles = allPropertiesFiles.stream()
+ .filter(p -> p.endsWith("other.properties"))
+ .collect(Collectors.toCollection(TreeSet::new));
+ jsonFiles = allJsonFiles.stream()
+ .filter(p -> {
+ Path m = getModule(p);
+ switch (m.getFileName().toString()) {
+ case "camel-core-osgi":
+ case "camel-core-xml":
+ case "camel-box":
+ case "camel-http-base":
+ case "camel-http-common":
+ case "camel-jetty-common":
+ case "camel-as2":
+ case "camel-olingo2":
+ case "camel-olingo4":
+ case "camel-servicenow":
+ case "camel-salesforce":
+ case "camel-fhir":
+ case "camel-debezium-common":
+ return false;
+ default:
+ return true;
}
- }
- }
- }
- // nothing in camel-core
+ })
+ .filter(p -> allModels.get(p) instanceof OtherModel)
+ .collect(Collectors.toCollection(TreeSet::new));
getLog().info("Found " + otherFiles.size() + " other.properties files");
getLog().info("Found " + jsonFiles.size() + " other json files");
// make sure to create out dir
- othersOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = othersOutDir.list() == null || othersOutDir.list().length == 0;
-
- for (File file : jsonFiles) {
- File to = new File(othersOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateJsonFiles.add(to);
- getLog().warn("Duplicate other name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
- }
- }
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
+ Files.createDirectories(othersOutDir);
- // check if we have a label as we want the other to include labels
- try {
- String text = PackageHelper.loadText(file);
- String name = asComponentName(file);
- Matcher matcher = LABEL_PATTERN.matcher(text);
- // grab the label, and remember it in the used labels
- if (matcher.find()) {
- String label = matcher.group(1);
- String[] labels = label.split(",");
- for (String s : labels) {
- Set<String> others = usedLabels.computeIfAbsent(s, k -> new TreeSet<>());
- others.add(name);
- }
- }
+ // Check duplicates
+ duplicateJsonFiles = getDuplicates(jsonFiles);
- // detect missing first version
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema("other", text, false);
- String firstVersion = null;
- for (Map<String, String> row : rows) {
- if (row.get("firstVersion") != null) {
- firstVersion = row.get("firstVersion");
- }
- }
- if (firstVersion == null) {
- missingFirstVersions.add(file);
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(jsonFiles, p -> p, p -> othersOutDir.resolve(p.getFileName()));
+ list(othersOutDir)
+ .filter(p -> !newJsons.containsValue(p))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
+
+ for (Path file : jsonFiles) {
+
+ OtherModel model = (OtherModel) allModels.get(file);
+
+ String name = asComponentName(file);
+
+ // grab the label, and remember it in the used labels
+ String label = model.getLabel();
+ if (!Strings.isNullOrEmpty(label)) {
+ String[] labels = label.split(",");
+ for (String s : labels) {
+ usedLabels.computeIfAbsent(s, k -> new TreeSet<>()).add(name);
}
+ }
- } catch (IOException e) {
- // ignore
+ // detect missing first version
+ String firstVersion = model.getFirstVersion();
+ if (Strings.isNullOrEmpty(firstVersion)) {
+ missingFirstVersions.add(file);
}
}
- Set<String> answer = generateJsonList(othersOutDir.toPath(), "../others.properties");
+ Path all = othersOutDir.resolve("../others.properties");
+ Set<String> otherNames = jsonFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", otherNames) + "\n");
printOthersReport(jsonFiles, duplicateJsonFiles, usedLabels, missingFirstVersions);
- return answer;
+ return otherNames;
}
- protected void executeArchetypes() throws MojoExecutionException, MojoFailureException {
+ protected void executeArchetypes() throws Exception {
+ Path archetypesDir = this.archetypesDir.toPath();
+ Path archetypesOutDir = this.archetypesOutDir.toPath();
+
getLog().info("Copying Archetype Catalog");
// find the generate catalog
- File file = new File(archetypesDir, "target/classes/archetype-catalog.xml");
-
- // make sure to create out dir
- archetypesOutDir.mkdirs();
-
- if (file.exists() && file.isFile()) {
- File to = new File(archetypesOutDir, file.getName());
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
- }
+ copyFile(archetypesDir.resolve("target/classes/archetype-catalog.xml"),
+ archetypesOutDir);
}
- protected void executeXmlSchemas() throws MojoExecutionException, MojoFailureException {
- getLog().info("Copying Spring/Blueprint XML schemas");
+ protected void executeXmlSchemas() throws Exception {
+ Path schemasOutDir = this.schemasOutDir.toPath();
+ Path springSchemaDir = this.springSchemaDir.toPath();
+ Path blueprintSchemaDir = this.blueprintSchemaDir.toPath();
- schemasOutDir.mkdirs();
+ getLog().info("Copying Spring/Blueprint XML schemas");
- File file = new File(springSchemaDir, "camel-spring.xsd");
- if (file.exists() && file.isFile()) {
- File to = new File(schemasOutDir, file.getName());
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
- }
- file = new File(blueprintSchemaDir, "camel-blueprint.xsd");
- if (file.exists() && file.isFile()) {
- File to = new File(schemasOutDir, file.getName());
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
- }
+ copyFile(springSchemaDir.resolve("camel-spring.xsd"), schemasOutDir);
+ copyFile(blueprintSchemaDir.resolve("camel-blueprint.xsd"), schemasOutDir);
}
- protected void executeMain() throws MojoExecutionException, MojoFailureException {
+ protected void executeMain() throws Exception {
getLog().info("Copying camel-main metadata");
- mainOutDir.mkdirs();
-
- File file = new File(mainDir, "camel-main-configuration-metadata.json");
- if (file.exists() && file.isFile()) {
- File to = new File(mainOutDir, file.getName());
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
- }
- }
+ copyFile(mainDir.toPath().resolve("camel-main-configuration-metadata.json"),
+ mainOutDir.toPath());
}
- protected void executeDocuments(Set<String> components, Set<String> dataformats, Set<String> languages, Set<String> others)
- throws MojoExecutionException, MojoFailureException {
+ protected void executeDocuments(Set<String> components, Set<String> dataformats, Set<String> languages, Set<String> others) throws Exception {
+ Path documentsOutDir = this.documentsOutDir.toPath();
+
getLog().info("Copying all Camel documents (ascii docs)");
// lets use sorted set/maps
- Set<File> adocFiles = new TreeSet<>();
- Set<File> missingAdocFiles = new TreeSet<>();
- Set<File> duplicateAdocFiles = new TreeSet<>();
+ Set<Path> adocFiles = new TreeSet<>();
+ Set<Path> missingAdocFiles = new TreeSet<>();
+ Set<Path> duplicateAdocFiles = new TreeSet<>();
// find all camel maven modules
- if (componentsDir != null && componentsDir.isDirectory()) {
- File[] componentFiles = componentsDir.listFiles();
- if (componentFiles != null) {
- for (File dir : componentFiles) {
- if (dir.isDirectory() && !"target".equals(dir.getName()) && !dir.getName().startsWith(".") && !excludeDocumentDir(dir.getName())) {
- File target = new File(dir, "src/main/docs");
-
- // special for these as they are in sub dir
- if ("camel-as2".equals(dir.getName())) {
- target = new File(dir, "camel-as2-component/src/main/docs");
- } else if ("camel-salesforce".equals(dir.getName())) {
- target = new File(dir, "camel-salesforce-component/src/main/docs");
- } else if ("camel-olingo2".equals(dir.getName())) {
- target = new File(dir, "camel-olingo2-component/src/main/docs");
- } else if ("camel-olingo4".equals(dir.getName())) {
- target = new File(dir, "camel-olingo4-component/src/main/docs");
- } else if ("camel-box".equals(dir.getName())) {
- target = new File(dir, "camel-box-component/src/main/docs");
- } else if ("camel-servicenow".equals(dir.getName())) {
- target = new File(dir, "camel-servicenow-component/src/main/docs");
- } else if ("camel-fhir".equals(dir.getName())) {
- target = new File(dir, "camel-fhir-component/src/main/docs");
- } else {
- // this module must be active with a source folder
- File src = new File(dir, "src");
- boolean active = src.isDirectory() && src.exists();
- if (!active) {
- continue;
- }
- }
-
- int before = adocFiles.size();
- findAsciiDocFilesRecursive(target, adocFiles, new CamelAsciiDocFileFilter());
- int after = adocFiles.size();
-
- if (before == after) {
- missingAdocFiles.add(dir);
- }
+ Stream.concat(
+ list(componentsDir.toPath())
+ .filter(dir -> !"target".equals(dir.getFileName().toString()))
+ .map(this::getComponentPath),
+ Stream.of(coreDir.toPath(), baseDir.toPath(), jaxpDir.toPath()))
+ .forEach(dir -> {
+ List<Path> l = PackageHelper.walk(dir.resolve("src/main/docs"))
+ .filter(f -> f.getFileName().toString().endsWith(".adoc"))
+ .collect(Collectors.toList());
+ if (l.isEmpty()) {
+ missingAdocFiles.add(dir);
}
- }
- }
- }
- if (coreDir != null && coreDir.isDirectory()) {
- File target = new File(coreDir, "src/main/docs");
- findAsciiDocFilesRecursive(target, adocFiles, new CamelAsciiDocFileFilter());
- }
- if (baseDir != null && baseDir.isDirectory()) {
- File target = new File(baseDir, "src/main/docs");
- findAsciiDocFilesRecursive(target, adocFiles, new CamelAsciiDocFileFilter());
- // also look in camel-jaxp
- target = new File(coreDir, "../camel-jaxp/src/main/docs");
- findAsciiDocFilesRecursive(target, adocFiles, new CamelAsciiDocFileFilter());
- }
+ adocFiles.addAll(l);
+ });
getLog().info("Found " + adocFiles.size() + " ascii document files");
// make sure to create out dir
- documentsOutDir.mkdirs();
- // we only want to warn for duplicates if its a clean build
- boolean warnDups = documentsOutDir.list() == null || documentsOutDir.list().length == 0;
+ Files.createDirectories(documentsOutDir);
+
+ // Check duplicates
+ duplicateAdocFiles = getDuplicates(adocFiles);
+
+ // Copy all descriptors
+ Map<Path, Path> newJsons = map(adocFiles, p -> p, p -> documentsOutDir.resolve(p.getFileName()));
+ list(documentsOutDir)
+ .filter(p -> !newJsons.containsValue(p)
+ && !newJsons.containsValue(p.resolveSibling(p.getFileName().toString().replace(".html", ".adoc"))))
+ .forEach(this::delete);
+ newJsons.forEach(this::copy);
// use ascii doctor to convert the adoc files to html so we have
// documentation in this format as well
@@ -963,96 +758,50 @@ public class PrepareCatalogMojo extends AbstractMojo {
int converted = 0;
- for (File file : adocFiles) {
- File to = new File(documentsOutDir, file.getName());
- if (to.exists()) {
- if (warnDups) {
- duplicateAdocFiles.add(to);
- getLog().warn("Duplicate document name detected: " + to);
- } else if (file.lastModified() < to.lastModified()) {
- getLog().debug("Skipping generated file: " + to);
- continue;
- } else {
- getLog().warn("Stale file: " + to);
- }
- }
- try {
- copyFile(file, to);
- } catch (IOException e) {
- throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
+ for (Path file : adocFiles) {
+ // convert adoc to html as well
+ String fileName = file.getFileName().toString();
+ String newName = fileName.substring(0, fileName.length() - ".adoc".length()) + ".html";
+ Path toHtml = documentsOutDir.resolve(newName);
+
+ if (Files.isRegularFile(toHtml)
+ && Files.getLastModifiedTime(file).compareTo(Files.getLastModifiedTime(toHtml)) < 0) {
+ getLog().debug("Skipping up to date html -> " + toHtml);
+ continue;
}
- // convert adoc to html as well
- if (file.getName().endsWith(".adoc")) {
- String newName = file.getName().substring(0, file.getName().length() - 5) + ".html";
- File toHtml = new File(documentsOutDir, newName);
-
- getLog().debug("Converting ascii document to html -> " + toHtml);
- asciidoctor.convertFile(file, OptionsBuilder.options().toFile(toHtml));
-
- converted++;
-
- try {
- // now fix the html file because we don't want to include
- // certain lines
- List<String> lines = FileUtils.readLines(toHtml, Charset.defaultCharset());
- List<String> output = new ArrayList<>();
- for (String line : lines) {
- // skip these lines
- if (line.contains("% raw %") || line.contains("% endraw %")) {
- continue;
- }
- output.add(line);
- }
- if (lines.size() != output.size()) {
- FileUtils.writeLines(toHtml, output, false);
- }
- } catch (IOException e) {
- // ignore
+ getLog().debug("Converting ascii document to html -> " + toHtml);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ asciidoctor.convertFile(file.toFile(), OptionsBuilder.options().toStream(new PrintStream(baos) {
+ public void write(RubyString str) {
+ this.append(str);
}
- }
+ }));
+
+ converted++;
+
+ // now fix the html file because we don't want to include certain lines
+ String data = Stream.of(new String(baos.toByteArray()).split("\n"))
+ .filter(line -> !line.contains("% raw %") && !line.contains("% endraw %"))
+ .collect(Collectors.joining("\n")) + "\n";
+ FileUtil.updateFile(toHtml, data);
}
if (converted > 0) {
getLog().info("Converted " + converted + " ascii documents to HTML");
}
- Set<String> docs = new LinkedHashSet<>();
-
- File all = new File(documentsOutDir, "../docs.properties");
- try {
- FileOutputStream fos = new FileOutputStream(all, false);
-
- String[] names = documentsOutDir.list();
- List<String> documents = new ArrayList<>();
- // sort the names
- for (String name : names) {
- if (name.endsWith(".adoc")) {
- // strip out .adoc from the name
- String documentName = name.substring(0, name.length() - 5);
- documents.add(documentName);
- }
- }
-
- Collections.sort(documents);
- for (String name : documents) {
- fos.write(name.getBytes());
- fos.write("\n".getBytes());
-
- docs.add(name);
- }
-
- fos.close();
-
- } catch (IOException e) {
- throw new MojoFailureException("Error writing to file " + all);
- }
+ Path all = documentsOutDir.resolve("../docs.properties");
+ Set<String> docNames = adocFiles.stream()
+ .map(PrepareCatalogMojo::asComponentName)
+ .collect(Collectors.toCollection(TreeSet::new));
+ FileUtil.updateFile(all, String.join("\n", docNames) + "\n");
printDocumentsReport(adocFiles, duplicateAdocFiles, missingAdocFiles);
// find out if we have documents for each component / dataformat /
// languages / others
- printMissingDocumentsReport(docs, components, dataformats, languages, others);
+ printMissingDocumentsReport(docNames, components, dataformats, languages, others);
}
private void printMissingDocumentsReport(Set<String> docs, Set<String> components, Set<String> dataformats, Set<String> languages, Set<String> others) {
@@ -1063,11 +812,20 @@ public class PrepareCatalogMojo extends AbstractMojo {
List<String> missing = new ArrayList<>();
for (String component : components) {
// special for mail
- if (component.equals("imap") || component.equals("imaps") || component.equals("pop3") || component.equals("pop3s") || component.equals("smtp")
- || component.equals("smtps")) {
- component = "mail";
- } else if (component.equals("ftp") || component.equals("sftp") || component.equals("ftps")) {
- component = "ftp";
+ switch (component) {
+ case "imap":
+ case "imaps":
+ case "pop3":
+ case "pop3s":
+ case "smtp":
+ case "smtps":
+ component = "mail";
+ break;
+ case "ftp":
+ case "sftp":
+ case "ftps":
+ component = "ftp";
+ break;
}
String name = component + "-component";
if (!docs.contains(name) && (!component.equalsIgnoreCase("salesforce") && !component.equalsIgnoreCase("servicenow"))) {
@@ -1136,27 +894,27 @@ public class PrepareCatalogMojo extends AbstractMojo {
getLog().info("================================================================================");
}
- private void printModelsReport(Set<File> json, Set<File> duplicate, Set<File> missingLabels, Map<String, Set<String>> usedLabels, Set<File> missingJavaDoc) {
+ private void printModelsReport(Set<Path> json, Set<Path> duplicate, Set<Path> missingLabels, Map<String, Set<String>> usedLabels, Set<Path> missingJavaDoc) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel model catalog report");
getLog().info("");
getLog().info("\tModels found: " + json.size());
- for (File file : json) {
+ for (Path file : json) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate models detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
if (!missingLabels.isEmpty()) {
getLog().info("");
getLog().warn("\tMissing labels detected: " + missingLabels.size());
- for (File file : missingLabels) {
+ for (Path file : missingLabels) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1173,7 +931,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missingJavaDoc.isEmpty()) {
getLog().info("");
getLog().warn("\tMissing javadoc on models: " + missingJavaDoc.size());
- for (File file : missingJavaDoc) {
+ for (Path file : missingJavaDoc) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1181,20 +939,20 @@ public class PrepareCatalogMojo extends AbstractMojo {
getLog().info("================================================================================");
}
- private void printComponentsReport(Set<File> json, Set<File> duplicate, Set<File> missing, Map<String, Set<String>> usedComponentLabels, Set<String> usedOptionsLabels,
- Set<String> unusedLabels, Set<File> missingFirstVersions) {
+ private void printComponentsReport(Set<Path> json, Set<Path> duplicate, Set<Path> missing, Map<String, Set<String>> usedComponentLabels,
+ Set<String> usedOptionsLabels, Set<String> unusedLabels, Set<Path> missingFirstVersions) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel component catalog report");
getLog().info("");
getLog().info("\tComponents found: " + json.size());
- for (File file : json) {
+ for (Path file : json) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate components detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1225,34 +983,34 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missing.isEmpty()) {
getLog().info("");
getLog().warn("\tMissing components detected: " + missing.size());
- for (File name : missing) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missing) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
if (!missingFirstVersions.isEmpty()) {
getLog().info("");
getLog().warn("\tComponents without firstVersion defined: " + missingFirstVersions.size());
- for (File name : missingFirstVersions) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missingFirstVersions) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
getLog().info("");
getLog().info("================================================================================");
}
- private void printDataFormatsReport(Set<File> json, Set<File> duplicate, Map<String, Set<String>> usedLabels, Set<File> missingFirstVersions) {
+ private void printDataFormatsReport(Set<Path> json, Set<Path> duplicate, Map<String, Set<String>> usedLabels, Set<Path> missingFirstVersions) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel data format catalog report");
getLog().info("");
getLog().info("\tDataFormats found: " + json.size());
- for (File file : json) {
+ for (Path file : json) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate dataformat detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1269,27 +1027,27 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missingFirstVersions.isEmpty()) {
getLog().info("");
getLog().warn("\tDataFormats without firstVersion defined: " + missingFirstVersions.size());
- for (File name : missingFirstVersions) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missingFirstVersions) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
getLog().info("");
getLog().info("================================================================================");
}
- private void printLanguagesReport(Set<File> json, Set<File> duplicate, Map<String, Set<String>> usedLabels, Set<File> missingFirstVersions) {
+ private void printLanguagesReport(Set<Path> json, Set<Path> duplicate, Map<String, Set<String>> usedLabels, Set<Path> missingFirstVersions) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel language catalog report");
getLog().info("");
getLog().info("\tLanguages found: " + json.size());
- for (File file : json) {
+ for (Path file : json) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate language detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1306,27 +1064,27 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missingFirstVersions.isEmpty()) {
getLog().info("");
getLog().warn("\tLanguages without firstVersion defined: " + missingFirstVersions.size());
- for (File name : missingFirstVersions) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missingFirstVersions) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
getLog().info("");
getLog().info("================================================================================");
}
- private void printOthersReport(Set<File> json, Set<File> duplicate, Map<String, Set<String>> usedLabels, Set<File> missingFirstVersions) {
+ private void printOthersReport(Set<Path> json, Set<Path> duplicate, Map<String, Set<String>> usedLabels, Set<Path> missingFirstVersions) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel other catalog report");
getLog().info("");
getLog().info("\tOthers found: " + json.size());
- for (File file : json) {
+ for (Path file : json) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate other detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1343,27 +1101,27 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missingFirstVersions.isEmpty()) {
getLog().info("");
getLog().warn("\tOthers without firstVersion defined: " + missingFirstVersions.size());
- for (File name : missingFirstVersions) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missingFirstVersions) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
getLog().info("");
getLog().info("================================================================================");
}
- private void printDocumentsReport(Set<File> docs, Set<File> duplicate, Set<File> missing) {
+ private void printDocumentsReport(Set<Path> docs, Set<Path> duplicate, Set<Path> missing) {
getLog().info("================================================================================");
getLog().info("");
getLog().info("Camel document catalog report");
getLog().info("");
getLog().info("\tDocuments found: " + docs.size());
- for (File file : docs) {
+ for (Path file : docs) {
getLog().info("\t\t" + asComponentName(file));
}
if (!duplicate.isEmpty()) {
getLog().info("");
getLog().warn("\tDuplicate document detected: " + duplicate.size());
- for (File file : duplicate) {
+ for (Path file : duplicate) {
getLog().warn("\t\t" + asComponentName(file));
}
}
@@ -1371,236 +1129,138 @@ public class PrepareCatalogMojo extends AbstractMojo {
if (!missing.isEmpty()) {
getLog().info("");
getLog().warn("\tMissing document detected: " + missing.size());
- for (File name : missing) {
- getLog().warn("\t\t" + name.getName());
+ for (Path name : missing) {
+ getLog().warn("\t\t" + name.getFileName().toString());
}
}
getLog().info("");
getLog().info("================================================================================");
}
- private static String asComponentName(File file) {
- String name = file.getName();
- if (name.endsWith(PackageHelper.JSON_SUFIX) || name.endsWith(".adoc")) {
- return name.substring(0, name.length() - 5);
+ private static String asComponentName(Path file) {
+ String name = file.getFileName().toString();
+ if (name.endsWith(PackageHelper.JSON_SUFIX)) {
+ return name.substring(0, name.length() - PackageHelper.JSON_SUFIX.length());
+ } else if (name.endsWith(".adoc")) {
+ return name.substring(0, name.length() - ".adoc".length());
}
return name;
}
- private void findComponentFilesRecursive(File dir, Set<File> found, Set<File> components, FileFilter filter) {
- File[] files = dir.listFiles(filter);
- if (files != null) {
- for (File file : files) {
- // skip files in root dirs as Camel does not store information
- // there but others may do
- boolean rootDir = "classes".equals(dir.getName()) || "META-INF".equals(dir.getName());
- boolean jsonFile = !rootDir && file.isFile() && file.getName().endsWith(PackageHelper.JSON_SUFIX);
- boolean componentFile = !rootDir && file.isFile() && file.getName().equals("component.properties");
- if (jsonFile) {
- found.add(file);
- } else if (componentFile) {
- components.add(file);
- } else if (file.isDirectory()) {
- findComponentFilesRecursive(file, found, components, filter);
- }
- }
- }
- }
-
- private void findDataFormatFilesRecursive(File dir, Set<File> found, Set<File> dataFormats, FileFilter filter) {
- File[] files = dir.listFiles(filter);
- if (files != null) {
- for (File file : files) {
- // skip files in root dirs as Camel does not store information
- // there but others may do
- boolean rootDir = "classes".equals(dir.getName()) || "META-INF".equals(dir.getName());
- boolean jsonFile = !rootDir && file.isFile() && file.getName().endsWith(PackageHelper.JSON_SUFIX);
- boolean dataFormatFile = !rootDir && file.isFile() && file.getName().equals("dataformat.properties");
- if (jsonFile) {
- found.add(file);
- } else if (dataFormatFile) {
- dataFormats.add(file);
- } else if (file.isDirectory()) {
- findDataFormatFilesRecursive(file, found, dataFormats, filter);
- }
- }
- }
- }
-
- private void findLanguageFilesRecursive(File dir, Set<File> found, Set<File> languages, FileFilter filter) {
- File[] files = dir.listFiles(filter);
- if (files != null) {
- for (File file : files) {
- // skip files in root dirs as Camel does not store information
- // there but others may do
- boolean rootDir = "classes".equals(dir.getName()) || "META-INF".equals(dir.getName());
- boolean jsonFile = !rootDir && file.isFile() && file.getName().endsWith(PackageHelper.JSON_SUFIX);
- boolean languageFile = !rootDir && file.isFile() && file.getName().equals("language.properties");
- if (jsonFile) {
- found.add(file);
- } else if (languageFile) {
- languages.add(file);
- } else if (file.isDirectory()) {
- findLanguageFilesRecursive(file, found, languages, filter);
- }
+ private void copyFile(Path file, Path toDir) throws IOException, MojoFailureException {
+ if (Files.isRegularFile(file)) {
+ // make sure to create out dir
+ Files.createDirectories(toDir);
+ // copy the file
+ Path to = toDir.resolve(file.getFileName());
+ try {
+ FileUtil.updateFile(file, to);
+ } catch (IOException e) {
+ throw new MojoFailureException("Cannot copy file from " + file + " -> " + to, e);
}
}
}
- private void findOtherFilesRecursive(File dir, Set<File> found, Set<File> others, FileFilter filter) {
- File[] files = dir.listFiles(filter);
- if (files != null) {
- for (File file : files) {
- // skip files in root dirs as Camel does not store information
- // there but others may do
- boolean rootDir = "classes".equals(dir.getName()) || "META-INF".equals(dir.getName());
- boolean jsonFile = rootDir && file.isFile() && file.getName().endsWith(PackageHelper.JSON_SUFIX);
- boolean otherFile = !rootDir && file.isFile() && file.getName().equals("other.properties");
- if (jsonFile) {
- found.add(file);
- } else if (otherFile) {
- others.add(file);
- } else if (file.isDirectory()) {
- findOtherFilesRecursive(file, found, others, filter);
- }
+ private static boolean excludeDocumentDir(String name) {
+ for (String exclude : EXCLUDE_DOC_FILES) {
+ if (exclude.equals(name)) {
+ return true;
}
}
+ return false;
}
- private void findAsciiDocFilesRecursive(File dir, Set<File> found, FileFilter filter) {
- File[] files = dir.listFiles(filter);
- if (files != null) {
- for (File file : files) {
- // skip files in root dirs as Camel does not store information
- // there but others may do
- boolean rootDir = "classes".equals(dir.getName()) || "META-INF".equals(dir.getName());
- boolean adocFile = !rootDir && file.isFile() && file.getName().endsWith(".adoc");
- if (adocFile) {
- found.add(file);
- } else if (file.isDirectory()) {
- findAsciiDocFilesRecursive(file, found, filter);
- }
- }
- }
+ private List<Path> concat(List<Path> l1, List<Path> l2) {
+ return Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList());
}
- private class CamelComponentsFileFilter implements FileFilter {
+ // CHECKSTYLE:ON
- @Override
- public boolean accept(File pathname) {
- if (pathname.isDirectory() && pathname.getName().equals("model")) {
- // do not check the camel-core model packages as there is no
- // components there
- return false;
- }
- if (pathname.isFile() && pathname.getName().endsWith(PackageHelper.JSON_SUFIX)) {
- // must be a components json file
- try {
- String json = PackageHelper.loadText(pathname);
- return "component".equals(PackageHelper.getSchemaKind(json));
- } catch (IOException e) {
- // ignore
- }
+ private Stream<Path> list(Path dir) {
+ try {
+ if (Files.isDirectory(dir)) {
+ return Files.list(dir);
+ } else {
+ return Stream.empty();
}
- return pathname.isDirectory() || (pathname.isFile() && pathname.getName().equals("component.properties"));
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to list files in directory: " + dir, e);
}
}
- private class CamelDataFormatsFileFilter implements FileFilter {
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.isDirectory() && pathname.getName().equals("model")) {
- // do not check the camel-core model packages as there is no
- // components there
- return false;
- }
- if (pathname.isFile() && pathname.getName().endsWith(PackageHelper.JSON_SUFIX)) {
- // must be a dataformat json file
- try {
- String json = PackageHelper.loadText(pathname);
- return "dataformat".equals(PackageHelper.getSchemaKind(json));
- } catch (IOException e) {
- // ignore
- }
- }
- return pathname.isDirectory() || (pathname.isFile() && pathname.getName().equals("dataformat.properties"));
+ private void delete(Path dir) {
+ try {
+ Files.delete(dir);
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to delete file: " + dir, e);
}
}
- private class CamelLanguagesFileFilter implements FileFilter {
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.isDirectory() && pathname.getName().equals("model")) {
- // do not check the camel-core model packages as there is no
- // components there
- return false;
- }
- if (pathname.isFile() && pathname.getName().endsWith(PackageHelper.JSON_SUFIX)) {
- // must be a language json file
- try {
- String json = PackageHelper.loadText(pathname);
- return "language".equals(PackageHelper.getSchemaKind(json));
- } catch (IOException e) {
- // ignore
+ private void copy(Path file, Path to) {
+ try {
+ try {
+ BasicFileAttributes af = Files.readAttributes(file, BasicFileAttributes.class);
+ BasicFileAttributes at = Files.readAttributes(to, BasicFileAttributes.class);
+ if (af.isRegularFile() && at.isRegularFile()
+ && af.size() == at.size()
+ && af.lastModifiedTime().compareTo(at.lastAccessTime()) < 0) {
+ // if same size and not modified, assume the same
+ return;
}
+ } catch (IOException e) {
+ // ignore and copy
}
- return pathname.isDirectory() || (pathname.isFile() && pathname.getName().equals("language.properties"));
+ FileUtil.updateFile(file, to);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy file from " + file + " -> " + to, e);
}
}
- private class CamelOthersFileFilter implements FileFilter {
-
- @Override
- public boolean accept(File pathname) {
- if (pathname.isFile() && pathname.getName().endsWith(PackageHelper.JSON_SUFIX)) {
- // must be a language json file
- try {
- String json = PackageHelper.loadText(pathname);
- return "other".equals(PackageHelper.getSchemaKind(json));
- } catch (IOException e) {
- // ignore
- }
- }
- return pathname.isDirectory() || (pathname.isFile() && pathname.getName().equals("other.properties"));
- }
+ private <U, K, V> Map<K, V> map(Collection<U> col, Function<U, K> key, Function<U, V> value) {
+ return col.stream().collect(Collectors.toMap(key, value));
}
- private class CamelAsciiDocFileFilter implements FileFilter {
-
- @Override
- public boolean accept(File pathname) {
- return pathname.isFile() && pathname.getName().endsWith(".adoc");
- }
+ private <U, K, V> Map<K, V> map(Collection<U> col, Function<U, K> key, Function<U, V> value, BinaryOperator<V> merger) {
+ return col.stream().collect(Collectors.toMap(key, value, merger));
}
- public static Set<String> generateJsonList(Path outDir, String outFile) throws MojoFailureException {
- Set<String> answer;
- Path all = outDir.resolve(outFile);
- try {
- answer = Files.list(outDir).filter(p -> p.getFileName().toString().endsWith(PackageHelper.JSON_SUFIX)).map(p -> p.getFileName().toString())
- // strip out .json from the name
- .map(n -> n.substring(0, n.length() - PackageHelper.JSON_SUFIX.length())).sorted().collect(LinkedHashSet::new, LinkedHashSet::add, LinkedHashSet::addAll);
- String data = String.join("\n", answer) + "\n";
- FileUtil.updateFile(all, data);
- return answer;
- } catch (IOException e) {
- throw new MojoFailureException("Error writing to file " + all);
+ private Path getModule(Path p) {
+ Path parent = p;
+ while (!parent.endsWith("target")) {
+ parent = parent.getParent();
}
+ return parent.getParent();
}
- public static void copyFile(File from, File to) throws IOException {
- FileUtil.updateFile(from.toPath(), to.toPath());
+ private Set<Path> getDuplicates(Set<Path> jsonFiles) {
+ Map<String, List<Path>> byName = map(jsonFiles,
+ PrepareCatalogMojo::asComponentName, // key by component name
+ Collections::singletonList, // value as a singleton list
+ this::concat); // merge lists
+ return byName.values().stream()
+ .flatMap(l -> l.stream().skip(1))
+ .collect(Collectors.toCollection(TreeSet::new));
}
- private static boolean excludeDocumentDir(String name) {
- for (String exclude : EXCLUDE_DOC_FILES) {
- if (exclude.equals(name)) {
- return true;
- }
+ private Path getComponentPath(Path dir) {
+ switch (dir.getFileName().toString()) {
+ case "camel-as2":
+ return dir.resolve("camel-as2-component");
+ case "camel-salesforce":
+ return dir.resolve("camel-salesforce-component");
+ case "camel-olingo2":
+ return dir.resolve("camel-olingo2-component");
+ case "camel-olingo4":
+ return dir.resolve("camel-olingo4-component");
+ case "camel-box":
+ return dir.resolve("camel-box-component");
+ case "camel-servicenow":
+ return dir.resolve("camel-servicenow-component");
+ case "camel-fhir":
+ return dir.resolve("camel-fhir-component");
+ default:
+ return dir;
}
- return false;
}
}
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareUserGuideMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareUserGuideMojo.java
index ef66838..c0f717a 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareUserGuideMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareUserGuideMojo.java
@@ -183,37 +183,36 @@ public class PrepareUserGuideMojo extends AbstractMojo {
}
}
- try {
- List<OtherModel> models = new ArrayList<>();
- for (File file : otherFiles) {
- String json = PackageHelper.loadText(file);
+ List<OtherModel> models = new ArrayList<>();
+ for (File file : otherFiles) {
+ try {
+ String json = PackageHelper.loadText(file);
OtherModel model = JsonMapper.generateOtherModel(json);
models.add(model);
+ } catch (Exception e) {
+ throw new MojoFailureException("Error reading file: " + file, e);
}
+ }
- // sort the models
- models.sort(BaseModel.compareTitle());
-
- // the summary file has the TOC
- File file = new File(userGuideDir, "SUMMARY.md");
+ // sort the models
+ models.sort(BaseModel.compareTitle());
- // update core components
- StringBuilder other = new StringBuilder();
- other.append("* Miscellaneous Components\n");
- for (OtherModel model : models) {
- String line = "\t* " + link(model) + "\n";
- other.append(line);
- }
- boolean updated = updateOthers(file, other.toString());
+ // the summary file has the TOC
+ File file = new File(userGuideDir, "SUMMARY.md");
- if (updated) {
- getLog().info("Updated user guide file: " + file);
- } else {
- getLog().debug("No changes to user guide file: " + file);
- }
+ // update core components
+ StringBuilder other = new StringBuilder();
+ other.append("* Miscellaneous Components\n");
+ for (OtherModel model : models) {
+ String line = "\t* " + link(model) + "\n";
+ other.append(line);
+ }
+ boolean updated = updateOthers(file, other.toString());
- } catch (IOException e) {
- throw new MojoFailureException("Error due " + e.getMessage(), e);
+ if (updated) {
+ getLog().info("Updated user guide file: " + file);
+ } else {
+ getLog().debug("No changes to user guide file: " + file);
}
}
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java
index a84bbe9..b5a6bc1 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java
@@ -18,12 +18,12 @@ package org.apache.camel.maven.packaging;
import java.io.File;
import java.io.IOException;
-import java.util.List;
import java.util.Map;
-import org.apache.camel.tooling.util.JSonSchemaHelper;
import org.apache.camel.tooling.util.PackageHelper;
-import org.apache.camel.tooling.util.Strings;
+import org.apache.camel.util.json.DeserializationException;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
/**
* Validation helper for validating components, data formats and languages
@@ -42,89 +42,50 @@ public final class ValidateHelper {
public static void validate(File file, ErrorDetail errorDetail) {
try {
String json = PackageHelper.loadText(file);
+ JsonObject obj = (JsonObject) Jsoner.deserialize(json);
- String kind = PackageHelper.getSchemaKind(json);
- boolean isComponent = "component".equals(kind);
- boolean isDataFormat = "dataformat".equals(kind);
- boolean isLanguage = "language".equals(kind);
+ Map<String, Object> model;
+ boolean isComponent = (model = obj.getMap("component")) != null;
+ boolean isDataFormat = !isComponent && (model = obj.getMap("dataformat")) != null;
+ boolean isLanguage = !isComponent && !isDataFormat && (model = obj.getMap("language")) != null;
// only check these kind
if (!isComponent && !isDataFormat && !isLanguage) {
return;
}
+ errorDetail.setKind((String) model.get("kind"));
+ errorDetail.setMissingDescription(isNullOrEmpty(model.get("description")));
+ errorDetail.setMissingLabel(isNullOrEmpty(model.get("label")));
if (isComponent) {
- errorDetail.setKind("component");
- } else if (isDataFormat) {
- errorDetail.setKind("dataformat");
- } else if (isLanguage) {
- errorDetail.setKind("language");
- }
-
- List<Map<String, String>> rows = JSonSchemaHelper.parseJsonSchema(errorDetail.getKind(), json, false);
- boolean label = false;
- boolean description = false;
- boolean syntax = false;
- for (Map<String, String> row : rows) {
- String value = row.get("label");
- if (!Strings.isEmpty(value)) {
- label = true;
- }
- value = row.get("description");
- if (!Strings.isEmpty(value)) {
- description = true;
- }
- value = row.get("syntax");
- if (!Strings.isEmpty(value)) {
- syntax = true;
- }
- }
-
- if (!label) {
- errorDetail.setMissingLabel(true);
- }
-
- if (!description) {
- errorDetail.setMissingDescription(true);
- }
-
- // syntax check is only for the components
- if (!syntax && isComponent) {
- errorDetail.setMissingSyntax(true);
- }
-
- if (isComponent) {
- // check all the component properties if they have description
- rows = JSonSchemaHelper.parseJsonSchema("componentProperties", json, true);
- for (Map<String, String> row : rows) {
- String key = row.get("name");
- String doc = row.get("description");
- if (doc == null || doc.isEmpty()) {
- errorDetail.addMissingComponentDoc(key);
+ errorDetail.setMissingSyntax(isNullOrEmpty(model.get("syntax")));
+ Map<String, Object> componentProps = obj.getMap("componentProperties");
+ for (Map.Entry<String, Object> entry : componentProps.entrySet()) {
+ if (isNullOrEmpty(((JsonObject) entry.getValue()).get("description"))) {
+ errorDetail.addMissingComponentDoc(entry.getKey());
}
}
}
-
- // check all the endpoint properties if they have description
- rows = JSonSchemaHelper.parseJsonSchema("properties", json, true);
+ Map<String, Object> props = obj.getMap("properties");
boolean path = false;
- for (Map<String, String> row : rows) {
- String key = row.get("name");
- String doc = row.get("description");
- if (doc == null || doc.isEmpty()) {
- errorDetail.addMissingEndpointDoc(key);
+ for (Map.Entry<String, Object> entry : props.entrySet()) {
+ JsonObject value = (JsonObject) entry.getValue();
+ if (isNullOrEmpty(value.get("description"))) {
+ errorDetail.addMissingEndpointDoc(entry.getKey());
}
- if ("path".equals(row.get("kind"))) {
- path = true;
- }
- }
- if (isComponent && !path) {
- // only components can have missing @UriPath
- errorDetail.setMissingUriPath(true);
+ path |= "path".equals(value.get("kind"));
}
- } catch (IOException e) {
+ errorDetail.setMissingUriPath(isComponent && !path);
+ } catch (DeserializationException e) {
+ // wrap parsing exceptions as runtime
+ throw new RuntimeException("Cannot parse json", e);
+ } catch (IOException e) {
// ignore
}
}
+ private static boolean isNullOrEmpty(Object obj) {
+ return obj == null || "".equals(obj);
+ }
+
}