You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/06/19 17:32:38 UTC

[3/9] camel git commit: Add goal to mvn plugin to validate if component docs is present when building each component.

Add goal to mvn plugin to validate if component docs is present when building each component.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/572f9e23
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/572f9e23
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/572f9e23

Branch: refs/heads/master
Commit: 572f9e230f6f9317976f0e848f1e87122110e720
Parents: 5e08a9e
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Jun 19 16:12:30 2015 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Jun 19 17:38:08 2015 +0200

----------------------------------------------------------------------
 components/pom.xml                              |  13 +-
 .../camel/maven/packaging/ErrorDetail.java      |  93 +++++++++++++
 .../maven/packaging/PrepareCatalogMojo.java     |   7 +
 .../camel/maven/packaging/StringHelper.java     |  15 ++
 .../maven/packaging/ValidateComponentMojo.java  | 139 +++++++++++++++++++
 .../camel/maven/packaging/ValidateHelper.java   | 138 ++++++++++++++++++
 6 files changed, 404 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/components/pom.xml
----------------------------------------------------------------------
diff --git a/components/pom.xml b/components/pom.xml
index c6fa5ba..057fd60 100644
--- a/components/pom.xml
+++ b/components/pom.xml
@@ -246,13 +246,24 @@
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-package-maven-plugin</artifactId>
         <version>${project.version}</version>
+        <configuration>
+          <validate>true</validate>
+        </configuration>
         <executions>
           <execution>
+            <id>prepare</id>
             <goals>
               <goal>prepare-components</goal>
             </goals>
             <phase>generate-resources</phase>
-          </execution>
+         </execution>
+          <execution>
+            <id>validate</id>
+            <goals>
+              <goal>validate-components</goal>
+            </goals>
+            <phase>prepare-package</phase>
+         </execution>
         </executions>
       </plugin>
     </plugins>

http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ErrorDetail.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ErrorDetail.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ErrorDetail.java
new file mode 100644
index 0000000..3266a58
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ErrorDetail.java
@@ -0,0 +1,93 @@
+/**
+ * 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.maven.packaging;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public final class ErrorDetail {
+
+    private String kind;
+
+    private boolean missingLabel;
+    private boolean missingDescription;
+    private boolean missingSyntax;
+    private boolean missingUriPath;
+    private List<String> missingComponentDocumentation = new ArrayList<>();
+    private List<String> missingEndpointDocumentation = new ArrayList<>();
+
+    public boolean hasErrors() {
+        return missingLabel || missingDescription || missingDescription || missingUriPath || !missingComponentDocumentation.isEmpty() || !missingEndpointDocumentation.isEmpty();
+    }
+
+    public String getKind() {
+        return kind;
+    }
+
+    public void setKind(String kind) {
+        this.kind = kind;
+    }
+
+    public boolean isMissingUriPath() {
+        return missingUriPath;
+    }
+
+    public void setMissingUriPath(boolean missingUriPath) {
+        this.missingUriPath = missingUriPath;
+    }
+
+    public boolean isMissingLabel() {
+        return missingLabel;
+    }
+
+    public void setMissingLabel(boolean missingLabel) {
+        this.missingLabel = missingLabel;
+    }
+
+    public boolean isMissingDescription() {
+        return missingDescription;
+    }
+
+    public void setMissingDescription(boolean missingDescription) {
+        this.missingDescription = missingDescription;
+    }
+
+    public boolean isMissingSyntax() {
+        return missingSyntax;
+    }
+
+    public void setMissingSyntax(boolean missingSyntax) {
+        this.missingSyntax = missingSyntax;
+    }
+
+    public void addMissingComponentDoc(String option) {
+        missingComponentDocumentation.add(option);
+    }
+
+    public void addMissingEndpointDoc(String option) {
+        missingEndpointDocumentation.add(option);
+    }
+
+    public List<String> getMissingComponentDocumentation() {
+        return missingComponentDocumentation;
+    }
+
+    public List<String> getMissingEndpointDocumentation() {
+        return missingEndpointDocumentation;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
----------------------------------------------------------------------
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 f0563bf..8405781 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
@@ -62,6 +62,13 @@ public class PrepareCatalogMojo extends AbstractMojo {
     protected MavenProject project;
 
     /**
+     * Whether to validate if the components, data formats, and languages are properly documented and have all the needed details.
+     *
+     * @parameter default-value="true"
+     */
+    protected Boolean validate;
+
+    /**
      * The output directory for components catalog
      *
      * @parameter default-value="${project.build.directory}/classes/org/apache/camel/catalog/components"

http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/StringHelper.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/StringHelper.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/StringHelper.java
index ac6a133..e17f430 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/StringHelper.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/StringHelper.java
@@ -16,11 +16,18 @@
  */
 package org.apache.camel.maven.packaging;
 
+import java.util.Collection;
+
 public final class StringHelper {
+
     private StringHelper() {
         // Utils Class
     }
 
+    public static boolean isEmpty(String s) {
+        return s == null || s.trim().isEmpty();
+    }
+
     public static String after(String text, String after) {
         if (!text.contains(after)) {
             return null;
@@ -43,4 +50,12 @@ public final class StringHelper {
         return before(text, before);
     }
 
+    public static String indentCollection(String indent, Collection<String> list) {
+        StringBuilder sb = new StringBuilder();
+        for (String text : list) {
+            sb.append(indent).append(text);
+        }
+        return sb.toString();
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateComponentMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateComponentMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateComponentMojo.java
new file mode 100644
index 0000000..58b3b11
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateComponentMojo.java
@@ -0,0 +1,139 @@
+/**
+ * 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.maven.packaging;
+
+import java.io.File;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import static org.apache.camel.maven.packaging.StringHelper.indentCollection;
+import static org.apache.camel.maven.packaging.ValidateHelper.asName;
+import static org.apache.camel.maven.packaging.ValidateHelper.validate;
+
+/**
+ * Validate a Camel component analyzing if the meta-data files for
+ * <ul>
+ *     <li>components</li>
+ *     <li>dataformats</li>
+ *     <li>languages</li>
+ * </ul>
+ * all contains the needed meta-data such as assigned labels, documentation for each option
+ *
+ * @goal validate-components
+ */
+public class ValidateComponentMojo extends AbstractMojo {
+
+    /**
+     * The maven project.
+     *
+     * @parameter property="project"
+     * @required
+     * @readonly
+     */
+    protected MavenProject project;
+
+    /**
+     * Whether to validate if the components, data formats, and languages are properly documented and have all the needed details.
+     *
+     * @parameter default-value="false"
+     */
+    protected Boolean validate;
+
+    /**
+     * The output directory for generated components file
+     *
+     * @parameter default-value="${project.build.directory}/classes/"
+     */
+    protected File outDir;
+
+    /**
+     * Maven ProjectHelper.
+     *
+     * @component
+     * @readonly
+     */
+    private MavenProjectHelper projectHelper;
+
+    /**
+     * build context to check changed files and mark them for refresh
+     * (used for m2e compatibility)
+     *
+     * @component
+     * @readonly
+     */
+    private BuildContext buildContext;
+    
+    /**
+     * Execute goal.
+     *
+     * @throws org.apache.maven.plugin.MojoExecutionException execution of the main class or one of the
+     *                                                        threads it generated failed.
+     * @throws org.apache.maven.plugin.MojoFailureException   something bad happened...
+     */
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+        final Set<File> jsonFiles = new TreeSet<>();
+        PackageHelper.findJsonFiles(outDir, jsonFiles, new PackageHelper.CamelComponentsModelFilter());
+
+        boolean failed = false;
+        if (validate) {
+            getLog().info("Validating ...");
+
+            for (File file : jsonFiles) {
+                final String name = asName(file);
+                final ErrorDetail detail = new ErrorDetail();
+
+                validate(file, detail);
+
+                if (detail.hasErrors()) {
+                    failed = true;
+                    getLog().warn("The " + detail.getKind() + ": " + name + " has errors!");
+                    if (detail.isMissingDescription()) {
+                        getLog().warn("Missing description on " + detail.getKind());
+                    }
+                    if (detail.isMissingLabel()) {
+                        getLog().warn("Missing label on " + detail.getKind());
+                    }
+                    if (detail.isMissingSyntax()) {
+                        getLog().warn("Missing syntax on endpoint");
+                    }
+                    if (detail.isMissingUriPath()) {
+                        getLog().warn("Missing @UriPath on endpoint");
+                    }
+                    if (!detail.getMissingComponentDocumentation().isEmpty()) {
+                        getLog().warn("Missing component documentation for the following options:" + indentCollection("\n\t", detail.getMissingComponentDocumentation()));
+                    }
+                    if (!detail.getMissingEndpointDocumentation().isEmpty()) {
+                        getLog().warn("Missing endpoint documentation for the following options:" + indentCollection("\n\t", detail.getMissingEndpointDocumentation()));
+                    }
+                }
+            }
+        }
+
+        if (failed) {
+            throw new MojoFailureException("There are validation errors, see above!");
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/572f9e23/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..4db0e73
--- /dev/null
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/ValidateHelper.java
@@ -0,0 +1,138 @@
+/**
+ * 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.maven.packaging;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.camel.maven.packaging.PackageHelper.loadText;
+
+/**
+ * Validation helper for validating components, data formats and languages
+ */
+public final class ValidateHelper {
+
+    private ValidateHelper() {
+    }
+
+    /**
+     * Validates the component json file
+     *
+     * @param file        the json file
+     * @param errorDetail details to add errors
+     */
+    public static void validate(File file, ErrorDetail errorDetail) {
+        String name = asName(file);
+
+        try {
+            String json = loadText(new FileInputStream(file));
+
+            boolean isComponent = json.contains("\"kind\": \"component\"");
+            boolean isDataFormat = json.contains("\"kind\": \"dataformat\"");
+            boolean isLanguage = json.contains("\"kind\": \"language\"");
+
+            // only check these kind
+            if (!isComponent && !isDataFormat && !isLanguage) {
+                return;
+            }
+
+            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 (!StringHelper.isEmpty(value)) {
+                    label = true;
+                }
+                value = row.get("description");
+                if (!StringHelper.isEmpty(value)) {
+                    description = true;
+                }
+                value = row.get("syntax");
+                if (!StringHelper.isEmpty(value)) {
+                    syntax = true;
+                }
+            }
+            if (!label) {
+                errorDetail.setMissingLabel(true);
+            }
+            if (!description) {
+                errorDetail.setMissingDescription(true);
+            }
+            if (!syntax) {
+                errorDetail.setMissingDescription(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);
+                    }
+                }
+            }
+
+            // check all the endpoint properties if they have description
+            rows = JSonSchemaHelper.parseJsonSchema("properties", json, true);
+            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);
+                }
+                String kind = row.get("kind");
+                if ("path".equals(kind)) {
+                    path = true;
+                }
+            }
+            if (isComponent && !path) {
+                // only components can have missing @UriPath
+                errorDetail.setMissingUriPath(true);
+            }
+        } catch (IOException e) {
+            // ignore
+        }
+    }
+
+    /**
+     * Returns the name of the component, data format or language from the given json file
+     */
+    public static String asName(File file) {
+        String name = file.getName();
+        if (name.endsWith(".json")) {
+            return name.substring(0, name.length() - 5);
+        }
+        return name;
+    }
+
+}