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 2016/12/05 12:47:24 UTC

camel git commit: CAMEL-10559: maven plugin to validate using the route parser. Donated from fabric8 project.

Repository: camel
Updated Branches:
  refs/heads/parser 550186e97 -> a20439f24


CAMEL-10559: maven plugin to validate using the route parser. Donated from fabric8 project.


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

Branch: refs/heads/parser
Commit: a20439f24de52a5e2ab4ee730b8196f61d3ef5f3
Parents: 550186e
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Dec 5 13:45:55 2016 +0100
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Dec 5 13:45:55 2016 +0100

----------------------------------------------------------------------
 tooling/maven/camel-maven-plugin/pom.xml        |  34 +-
 .../org/apache/camel/maven/ValidateMojo.java    | 639 +++++++++++++++++++
 .../camel/maven/helper/EndpointHelper.java      | 105 +++
 3 files changed, 777 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a20439f2/tooling/maven/camel-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-maven-plugin/pom.xml b/tooling/maven/camel-maven-plugin/pom.xml
index ec98c6b..fffc520 100644
--- a/tooling/maven/camel-maven-plugin/pom.xml
+++ b/tooling/maven/camel-maven-plugin/pom.xml
@@ -71,7 +71,39 @@
       <groupId>org.apache.camel</groupId>
       <artifactId>camel-cdi</artifactId>
     </dependency>
-    
+
+    <!-- camel-catalog -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-catalog</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-catalog-lucene</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-catalog-maven</artifactId>
+    </dependency>
+
+    <!-- camel route parser -->
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-route-parser</artifactId>
+    </dependency>
+
+    <!-- roaster java parser -->
+    <dependency>
+      <groupId>org.jboss.forge.roaster</groupId>
+      <artifactId>roaster-api</artifactId>
+      <version>${roaster-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.forge.roaster</groupId>
+      <artifactId>roaster-jdt</artifactId>
+      <version>${roaster-version}</version>
+    </dependency>
+
     <!-- logging -->
     <dependency>
       <groupId>org.apache.logging.log4j</groupId>

http://git-wip-us.apache.org/repos/asf/camel/blob/a20439f2/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/ValidateMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/ValidateMojo.java b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/ValidateMojo.java
new file mode 100644
index 0000000..c5ed912
--- /dev/null
+++ b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/ValidateMojo.java
@@ -0,0 +1,639 @@
+/**
+ * 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;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.camel.catalog.CamelCatalog;
+import org.apache.camel.catalog.DefaultCamelCatalog;
+import org.apache.camel.catalog.EndpointValidationResult;
+import org.apache.camel.catalog.SimpleValidationResult;
+import org.apache.camel.catalog.lucene.LuceneSuggestionStrategy;
+import org.apache.camel.catalog.maven.MavenVersionManager;
+import org.apache.camel.maven.helper.EndpointHelper;
+import org.apache.camel.parser.RouteBuilderParser;
+import org.apache.camel.parser.XmlRouteParser;
+import org.apache.camel.parser.model.CamelEndpointDetails;
+import org.apache.camel.parser.model.CamelSimpleExpressionDetails;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.mojo.exec.AbstractExecMojo;
+import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.JavaType;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
+
+/**
+ * Parses the source code and validates the Camel routes has valid endpoint uris and simple expressions.
+ *
+ * @goal validate
+ * @requiresDependencyResolution compile+runtime
+ * @execute phase="process-test-classes"
+ */
+public class ValidateMojo extends AbstractExecMojo {
+
+    /**
+     * The maven project.
+     *
+     * @parameter property="project"
+     * @required
+     * @readonly
+     */
+    protected MavenProject project;
+
+    /**
+     * Whether to fail if invalid Camel endpoints was found. By default the plugin logs the errors at WARN level
+     *
+     * @parameter property="camel.failOnError"
+     *            default-value="false"
+     */
+    private boolean failOnError;
+
+    /**
+     * Whether to log endpoint URIs which was un-parsable and therefore not possible to validate
+     *
+     * @parameter property="camel.logUnparseable"
+     *            default-value="false"
+     */
+    private boolean logUnparseable;
+
+    /**
+     * Whether to include Java files to be validated for invalid Camel endpoints
+     *
+     * @parameter property="camel.includeJava"
+     *            default-value="true"
+     */
+    private boolean includeJava;
+
+    /**
+     * Whether to include XML files to be validated for invalid Camel endpoints
+     *
+     * @parameter property="camel.includeXml"
+     *            default-value="true"
+     */
+    private boolean includeXml;
+
+    /**
+     * Whether to include test source code
+     *
+     * @parameter property="camel.includeTest"
+     *            default-value="false"
+     */
+    private boolean includeTest;
+
+    /**
+     * To filter the names of java and xml files to only include files matching any of the given list of patterns (wildcard and regular expression).
+     * Multiple values can be separated by comma.
+     *
+     * @parameter property="camel.includes"
+     */
+    private String includes;
+
+    /**
+     * To filter the names of java and xml files to exclude files matching any of the given list of patterns (wildcard and regular expression).
+     * Multiple values can be separated by comma.
+     *
+     * @parameter property="camel.excludes"
+     */
+    private String excludes;
+
+    /**
+     * Whether to ignore unknown components
+     *
+     * @parameter property="camel.ignoreUnknownComponent"
+     *            default-value="true"
+     */
+    private boolean ignoreUnknownComponent;
+
+    /**
+     * Whether to ignore incapable of parsing the endpoint uri
+     *
+     * @parameter property="camel.ignoreIncapable"
+     *            default-value="true"
+     */
+    private boolean ignoreIncapable;
+
+    /**
+     * Whether to ignore components that uses lenient properties. When this is true, then the uri validation is stricter
+     * but would fail on properties that are not part of the component but in the uri because of using lenient properties.
+     * For example using the HTTP components to provide query parameters in the endpoint uri.
+     *
+     * @parameter property="camel.ignoreLenientProperties"
+     *            default-value="true"
+     */
+    private boolean ignoreLenientProperties;
+
+    /**
+     * Whether to show all endpoints and simple expressions (both invalid and valid).
+     *
+     * @parameter property="camel.showAll"
+     *            default-value="false"
+     */
+    private boolean showAll;
+
+    /**
+     * Whether to allow downloading Camel catalog version from the internet. This is needed if the project
+     * uses a different Camel version than this plugin is using by default.
+     *
+     * @parameter property="camel.downloadVersion"
+     *            default-value="true"
+     */
+    private boolean downloadVersion;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        CamelCatalog catalog = new DefaultCamelCatalog();
+        // add activemq as known component
+        catalog.addComponent("activemq", "org.apache.activemq.camel.component.ActiveMQComponent");
+        // enable did you mean
+        catalog.setSuggestionStrategy(new LuceneSuggestionStrategy());
+        // enable loading other catalog versions dynamically
+        catalog.setVersionManager(new MavenVersionManager());
+        // enable caching
+        catalog.enableCache();
+
+        if (downloadVersion) {
+            String catalogVersion = catalog.getCatalogVersion();
+            String version = findCamelVersion(project);
+            if (version != null && !version.equals(catalogVersion)) {
+                // the project uses a different Camel version so attempt to load it
+                getLog().info("Downloading Camel version: " + version);
+                boolean loaded = catalog.loadVersion(version);
+                if (!loaded) {
+                    getLog().warn("Error downloading Camel version: " + version);
+                }
+            }
+        }
+
+        // if using the same version as the fabric8-camel-maven-plugin we must still load it
+        if (catalog.getLoadedVersion() == null) {
+            catalog.loadVersion(catalog.getCatalogVersion());
+        }
+
+        if (catalog.getLoadedVersion() != null) {
+            getLog().info("Using Camel version: " + catalog.getLoadedVersion());
+        } else {
+            // force load version from the fabric8-camel-maven-plugin
+            getLog().info("Using Camel version: " + catalog.getCatalogVersion());
+        }
+
+        List<CamelEndpointDetails> endpoints = new ArrayList<>();
+        List<CamelSimpleExpressionDetails> simpleExpressions = new ArrayList<>();
+        Set<File> javaFiles = new LinkedHashSet<File>();
+        Set<File> xmlFiles = new LinkedHashSet<File>();
+
+        // find all java route builder classes
+        if (includeJava) {
+            List list = project.getCompileSourceRoots();
+            for (Object obj : list) {
+                String dir = (String) obj;
+                findJavaFiles(new File(dir), javaFiles);
+            }
+            if (includeTest) {
+                list = project.getTestCompileSourceRoots();
+                for (Object obj : list) {
+                    String dir = (String) obj;
+                    findJavaFiles(new File(dir), javaFiles);
+                }
+            }
+        }
+        // find all xml routes
+        if (includeXml) {
+            List list = project.getResources();
+            for (Object obj : list) {
+                Resource dir = (Resource) obj;
+                findXmlFiles(new File(dir.getDirectory()), xmlFiles);
+            }
+            if (includeTest) {
+                list = project.getTestResources();
+                for (Object obj : list) {
+                    Resource dir = (Resource) obj;
+                    findXmlFiles(new File(dir.getDirectory()), xmlFiles);
+                }
+            }
+        }
+
+        for (File file : javaFiles) {
+            if (matchFile(file)) {
+                try {
+                    List<CamelEndpointDetails> fileEndpoints = new ArrayList<>();
+                    List<CamelSimpleExpressionDetails> fileSimpleExpressions = new ArrayList<>();
+                    List<String> unparsable = new ArrayList<>();
+
+                    // parse the java source code and find Camel RouteBuilder classes
+                    String fqn = file.getPath();
+                    String baseDir = ".";
+                    JavaType out = Roaster.parse(file);
+                    // we should only parse java classes (not interfaces and enums etc)
+                    if (out != null && out instanceof JavaClassSource) {
+                        JavaClassSource clazz = (JavaClassSource) out;
+                        RouteBuilderParser.parseRouteBuilderEndpoints(clazz, baseDir, fqn, fileEndpoints, unparsable, includeTest);
+                        RouteBuilderParser.parseRouteBuilderSimpleExpressions(clazz, baseDir, fqn, fileSimpleExpressions);
+
+                        // add what we found in this file to the total list
+                        endpoints.addAll(fileEndpoints);
+                        simpleExpressions.addAll(fileSimpleExpressions);
+
+                        // was there any unparsable?
+                        if (logUnparseable && !unparsable.isEmpty()) {
+                            for (String uri : unparsable) {
+                                getLog().warn("Cannot parse endpoint uri " + uri + " in java file " + file);
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    getLog().warn("Error parsing java file " + file + " code due " + e.getMessage(), e);
+                }
+            }
+        }
+        for (File file : xmlFiles) {
+            if (matchFile(file)) {
+                try {
+                    List<CamelEndpointDetails> fileEndpoints = new ArrayList<>();
+                    List<CamelSimpleExpressionDetails> fileSimpleExpressions = new ArrayList<>();
+
+                    // parse the xml source code and find Camel routes
+                    String fqn = file.getPath();
+                    String baseDir = ".";
+
+                    InputStream is = new FileInputStream(file);
+                    XmlRouteParser.parseXmlRouteEndpoints(is, baseDir, fqn, fileEndpoints);
+                    is.close();
+                    // need a new stream
+                    is = new FileInputStream(file);
+                    XmlRouteParser.parseXmlRouteSimpleExpressions(is, baseDir, fqn, fileSimpleExpressions);
+                    is.close();
+
+                    // add what we found in this file to the total list
+                    endpoints.addAll(fileEndpoints);
+                    simpleExpressions.addAll(fileSimpleExpressions);
+                } catch (Exception e) {
+                    getLog().warn("Error parsing xml file " + file + " code due " + e.getMessage(), e);
+                }
+            }
+        }
+
+        int endpointErrors = 0;
+        int unknownComponents = 0;
+        int incapableErrors = 0;
+        for (CamelEndpointDetails detail : endpoints) {
+            EndpointValidationResult result = catalog.validateEndpointProperties(detail.getEndpointUri(), ignoreLenientProperties);
+
+            boolean ok = result.isSuccess();
+            if (!ok && ignoreUnknownComponent && result.getUnknownComponent() != null) {
+                // if we failed due unknown component then be okay if we should ignore that
+                unknownComponents++;
+                ok = true;
+            }
+            if (!ok && ignoreIncapable && result.getIncapable() != null) {
+                // if we failed due incapable then be okay if we should ignore that
+                incapableErrors++;
+                ok = true;
+            }
+            if (!ok) {
+                if (result.getUnknownComponent() != null) {
+                    unknownComponents++;
+                } else if (result.getIncapable() != null) {
+                    incapableErrors++;
+                } else {
+                    endpointErrors++;
+                }
+
+                StringBuilder sb = new StringBuilder();
+                sb.append("Endpoint validation error at: ");
+                if (detail.getClassName() != null && detail.getLineNumber() != null) {
+                    // this is from java code
+                    sb.append(detail.getClassName());
+                    if (detail.getMethodName() != null) {
+                        sb.append(".").append(detail.getMethodName());
+                    }
+                    sb.append("(").append(asSimpleClassName(detail.getClassName())).append(".java:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else if (detail.getLineNumber() != null) {
+                    // this is from xml
+                    String fqn = stripRootPath(asRelativeFile(detail.getFileName()));
+                    if (fqn.endsWith(".xml")) {
+                        fqn = fqn.substring(0, fqn.length() - 4);
+                        fqn = asPackageName(fqn);
+                    }
+                    sb.append(fqn);
+                    sb.append("(").append(asSimpleClassName(fqn)).append(".xml:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else {
+                    sb.append(detail.getFileName());
+                }
+                sb.append("\n\n");
+                String out = result.summaryErrorMessage(false);
+                sb.append(out);
+                sb.append("\n\n");
+
+                getLog().warn(sb.toString());
+            } else if (showAll) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("Endpoint validation passsed at: ");
+                if (detail.getClassName() != null && detail.getLineNumber() != null) {
+                    // this is from java code
+                    sb.append(detail.getClassName());
+                    if (detail.getMethodName() != null) {
+                        sb.append(".").append(detail.getMethodName());
+                    }
+                    sb.append("(").append(asSimpleClassName(detail.getClassName())).append(".java:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else if (detail.getLineNumber() != null) {
+                    // this is from xml
+                    String fqn = stripRootPath(asRelativeFile(detail.getFileName()));
+                    if (fqn.endsWith(".xml")) {
+                        fqn = fqn.substring(0, fqn.length() - 4);
+                        fqn = asPackageName(fqn);
+                    }
+                    sb.append(fqn);
+                    sb.append("(").append(asSimpleClassName(fqn)).append(".xml:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else {
+                    sb.append(detail.getFileName());
+                }
+                sb.append("\n");
+                sb.append("\n\t").append(result.getUri());
+                sb.append("\n\n");
+
+                getLog().info(sb.toString());
+            }
+        }
+        String endpointSummary;
+        if (endpointErrors == 0) {
+            int ok = endpoints.size() - endpointErrors - incapableErrors - unknownComponents;
+            endpointSummary = String.format("Endpoint validation success: (%s = passed, %s = invalid, %s = incapable, %s = unknown components)", ok, endpointErrors, incapableErrors, unknownComponents);
+        } else {
+            int ok = endpoints.size() - endpointErrors - incapableErrors - unknownComponents;
+            endpointSummary = String.format("Endpoint validation error: (%s = passed, %s = invalid, %s = incapable, %s = unknown components)", ok, endpointErrors, incapableErrors, unknownComponents);
+        }
+
+        if (endpointErrors > 0) {
+            getLog().warn(endpointSummary);
+        } else {
+            getLog().info(endpointSummary);
+        }
+
+        int simpleErrors = 0;
+        for (CamelSimpleExpressionDetails detail : simpleExpressions) {
+            SimpleValidationResult result = catalog.validateSimpleExpression(detail.getSimple());
+            if (!result.isSuccess()) {
+                simpleErrors++;
+
+                StringBuilder sb = new StringBuilder();
+                sb.append("Simple validation error at: ");
+                if (detail.getClassName() != null && detail.getLineNumber() != null) {
+                    // this is from java code
+                    sb.append(detail.getClassName());
+                    if (detail.getMethodName() != null) {
+                        sb.append(".").append(detail.getMethodName());
+                    }
+                    sb.append("(").append(asSimpleClassName(detail.getClassName())).append(".java:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else if (detail.getLineNumber() != null) {
+                    // this is from xml
+                    String fqn = stripRootPath(asRelativeFile(detail.getFileName()));
+                    if (fqn.endsWith(".xml")) {
+                        fqn = fqn.substring(0, fqn.length() - 4);
+                        fqn = asPackageName(fqn);
+                    }
+                    sb.append(fqn);
+                    sb.append("(").append(asSimpleClassName(fqn)).append(".xml:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else {
+                    sb.append(detail.getFileName());
+                }
+                sb.append("\n");
+                String[] lines = result.getError().split("\n");
+                for (String line : lines) {
+                    sb.append("\n\t").append(line);
+                }
+                sb.append("\n");
+
+                getLog().warn(sb.toString());
+            } else if (showAll) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("Simple validation passed at: ");
+                if (detail.getClassName() != null && detail.getLineNumber() != null) {
+                    // this is from java code
+                    sb.append(detail.getClassName());
+                    if (detail.getMethodName() != null) {
+                        sb.append(".").append(detail.getMethodName());
+                    }
+                    sb.append("(").append(asSimpleClassName(detail.getClassName())).append(".java:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else if (detail.getLineNumber() != null) {
+                    // this is from xml
+                    String fqn = stripRootPath(asRelativeFile(detail.getFileName()));
+                    if (fqn.endsWith(".xml")) {
+                        fqn = fqn.substring(0, fqn.length() - 4);
+                        fqn = asPackageName(fqn);
+                    }
+                    sb.append(fqn);
+                    sb.append("(").append(asSimpleClassName(fqn)).append(".xml:");
+                    sb.append(detail.getLineNumber()).append(")");
+                } else {
+                    sb.append(detail.getFileName());
+                }
+                sb.append("\n");
+                sb.append("\n\t").append(result.getSimple());
+                sb.append("\n\n");
+
+                getLog().info(sb.toString());
+            }
+        }
+
+        String simpleSummary;
+        if (simpleErrors == 0) {
+            int ok = simpleExpressions.size() - simpleErrors;
+            simpleSummary = String.format("Simple validation success: (%s = passed, %s = invalid)", ok, simpleErrors);
+        } else {
+            int ok = simpleExpressions.size() - simpleErrors;
+            simpleSummary = String.format("Simple validation error: (%s = passed, %s = invalid)", ok, simpleErrors);
+        }
+
+        if (failOnError && (endpointErrors > 0 || simpleErrors > 0)) {
+            throw new MojoExecutionException(endpointSummary + "\n" + simpleSummary);
+        }
+
+        if (simpleErrors > 0) {
+            getLog().warn(simpleSummary);
+        } else {
+            getLog().info(simpleSummary);
+        }
+    }
+
+    private static String findCamelVersion(MavenProject project) {
+        Dependency candidate = null;
+
+        List list = project.getDependencies();
+        for (Object obj : list) {
+            Dependency dep = (Dependency) obj;
+            if ("org.apache.camel".equals(dep.getGroupId())) {
+                if ("camel-core".equals(dep.getArtifactId())) {
+                    // favor camel-core
+                    candidate = dep;
+                    break;
+                } else {
+                    candidate = dep;
+                }
+            }
+        }
+        if (candidate != null) {
+            return candidate.getVersion();
+        }
+
+        return null;
+    }
+
+    private void findJavaFiles(File dir, Set<File> javaFiles) {
+        File[] files = dir.isDirectory() ? dir.listFiles() : null;
+        if (files != null) {
+            for (File file : files) {
+                if (file.getName().endsWith(".java")) {
+                    javaFiles.add(file);
+                } else if (file.isDirectory()) {
+                    findJavaFiles(file, javaFiles);
+                }
+            }
+        }
+    }
+
+    private void findXmlFiles(File dir, Set<File> xmlFiles) {
+        File[] files = dir.isDirectory() ? dir.listFiles() : null;
+        if (files != null) {
+            for (File file : files) {
+                if (file.getName().endsWith(".xml")) {
+                    xmlFiles.add(file);
+                } else if (file.isDirectory()) {
+                    findXmlFiles(file, xmlFiles);
+                }
+            }
+        }
+    }
+
+    private boolean matchFile(File file) {
+        if (excludes == null && includes == null) {
+            return true;
+        }
+
+        // exclude take precedence
+        if (excludes != null) {
+            for (String exclude : excludes.split(",")) {
+                exclude = exclude.trim();
+                // try both with and without directory in the name
+                String fqn = stripRootPath(asRelativeFile(file.getAbsolutePath()));
+                boolean match = EndpointHelper.matchPattern(fqn, exclude) || EndpointHelper.matchPattern(file.getName(), exclude);
+                if (match) {
+                    return false;
+                }
+            }
+        }
+
+        // include
+        if (includes != null) {
+            for (String include : includes.split(",")) {
+                include = include.trim();
+                // try both with and without directory in the name
+                String fqn = stripRootPath(asRelativeFile(file.getAbsolutePath()));
+                boolean match = EndpointHelper.matchPattern(fqn, include) || EndpointHelper.matchPattern(file.getName(), include);
+                if (match) {
+                    return true;
+                }
+            }
+            // did not match any includes
+            return false;
+        }
+
+        // was not excluded nor failed include so its accepted
+        return true;
+    }
+
+    private String asRelativeFile(String name) {
+        String answer = name;
+
+        String base = project.getBasedir().getAbsolutePath();
+        if (name.startsWith(base)) {
+            answer = name.substring(base.length());
+            // skip leading slash for relative path
+            if (answer.startsWith(File.separator)) {
+                answer = answer.substring(1);
+            }
+        }
+        return answer;
+    }
+
+    private String stripRootPath(String name) {
+        // strip out any leading source / resource directory
+
+        List list = project.getCompileSourceRoots();
+        for (Object obj : list) {
+            String dir = (String) obj;
+            dir = asRelativeFile(dir);
+            if (name.startsWith(dir)) {
+                return name.substring(dir.length() + 1);
+            }
+        }
+        list = project.getTestCompileSourceRoots();
+        for (Object obj : list) {
+            String dir = (String) obj;
+            dir = asRelativeFile(dir);
+            if (name.startsWith(dir)) {
+                return name.substring(dir.length() + 1);
+            }
+        }
+        List resources = project.getResources();
+        for (Object obj : resources) {
+            Resource resource = (Resource) obj;
+            String dir = asRelativeFile(resource.getDirectory());
+            if (name.startsWith(dir)) {
+                return name.substring(dir.length() + 1);
+            }
+        }
+        resources = project.getTestResources();
+        for (Object obj : resources) {
+            Resource resource = (Resource) obj;
+            String dir = asRelativeFile(resource.getDirectory());
+            if (name.startsWith(dir)) {
+                return name.substring(dir.length() + 1);
+            }
+        }
+
+        return name;
+    }
+
+    private static String asPackageName(String name) {
+        return name.replace(File.separator, ".");
+    }
+
+    private static String asSimpleClassName(String className) {
+        int dot = className.lastIndexOf('.');
+        if (dot > 0) {
+            return className.substring(dot + 1);
+        } else {
+            return className;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a20439f2/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/EndpointHelper.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/EndpointHelper.java b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/EndpointHelper.java
new file mode 100644
index 0000000..94bed8c
--- /dev/null
+++ b/tooling/maven/camel-maven-plugin/src/main/java/org/apache/camel/maven/helper/EndpointHelper.java
@@ -0,0 +1,105 @@
+/**
+ * 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.helper;
+
+import java.util.regex.PatternSyntaxException;
+
+public final class EndpointHelper {
+
+    /**
+     * Matches the name with the given pattern.
+     * <p/>
+     * The match rules are applied in this order:
+     * <ul>
+     * <li>exact match, returns true</li>
+     * <li>wildcard match (pattern ends with a * and the name starts with the pattern), returns true</li>
+     * <li>regular expression match, returns true</li>
+     * <li>otherwise returns false</li>
+     * </ul>
+     *
+     * @param name    the name
+     * @param pattern a pattern to match
+     * @return <tt>true</tt> if match, <tt>false</tt> otherwise.
+     */
+    public static boolean matchPattern(String name, String pattern) {
+        if (name == null || pattern == null) {
+            return false;
+        }
+
+        if (name.equals(pattern)) {
+            // exact match
+            return true;
+        }
+
+        if (matchWildcard(name, pattern)) {
+            return true;
+        }
+
+        if (matchRegex(name, pattern)) {
+            return true;
+        }
+
+        // no match
+        return false;
+    }
+
+    /**
+     * Matches the name with the given pattern.
+     * <p/>
+     * The match rules are applied in this order:
+     * <ul>
+     * <li>wildcard match (pattern ends with a * and the name starts with the pattern), returns true</li>
+     * <li>otherwise returns false</li>
+     * </ul>
+     *
+     * @param name    the name
+     * @param pattern a pattern to match
+     * @return <tt>true</tt> if match, <tt>false</tt> otherwise.
+     */
+    private static boolean matchWildcard(String name, String pattern) {
+        // we have wildcard support in that hence you can match with: file* to match any file endpoints
+        if (pattern.endsWith("*") && name.startsWith(pattern.substring(0, pattern.length() - 1))) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Matches the name with the given pattern.
+     * <p/>
+     * The match rules are applied in this order:
+     * <ul>
+     * <li>regular expression match, returns true</li>
+     * <li>otherwise returns false</li>
+     * </ul>
+     *
+     * @param name    the name
+     * @param pattern a pattern to match
+     * @return <tt>true</tt> if match, <tt>false</tt> otherwise.
+     */
+    private static boolean matchRegex(String name, String pattern) {
+        // match by regular expression
+        try {
+            if (name.matches(pattern)) {
+                return true;
+            }
+        } catch (PatternSyntaxException e) {
+            // ignore
+        }
+        return false;
+    }
+}