You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by dh...@apache.org on 2014/06/10 21:51:36 UTC

[08/35] git commit: Refactored mojos, added JavadocApiMethodGenerator, ApiComponentGenerator

Refactored mojos, added JavadocApiMethodGenerator, ApiComponentGenerator


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

Branch: refs/heads/master
Commit: ecee7f1fcb48b2945aa6ebfd32c84226b86f6dfc
Parents: cd89e14
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Mon May 26 05:37:45 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Tue Jun 10 12:48:30 2014 -0700

----------------------------------------------------------------------
 .../camel/util/component/ApiMethodParser.java   |  16 +-
 .../camel-component-util-maven-plugin/pom.xml   |  15 ++
 .../maven/AbstractApiMethodGeneratorMojo.java   | 117 +++++++++
 .../camel/maven/AbstractGeneratorMojo.java      | 137 ++++++++++
 .../camel/maven/ApiComponentGeneratorMojo.java  | 109 ++++++++
 .../camel/maven/ApiMethodGeneratorMojo.java     | 197 ---------------
 .../java/org/apache/camel/maven/ApiProxy.java   | 100 ++++++++
 .../camel/maven/FileApiMethodGeneratorMojo.java |  34 +--
 .../maven/JavadocApiMethodGeneratorMojo.java    | 252 +++++++++++++++++++
 .../src/main/resources/api-collection.vm        |  46 ++++
 .../camel/maven/AbstractGeneratorMojoTest.java  |  35 +++
 .../maven/ApiComponentGeneratorMojoTest.java    |  78 ++++++
 .../apache/camel/maven/ApiMethodEnumTest.java   |  71 ------
 .../maven/FileApiMethodGeneratorMojoTest.java   |  67 +++++
 .../JavadocApiMethodGeneratorMojoTest.java      |  66 +++++
 .../test/resources/test-proxy-signatures.txt    |   7 +
 16 files changed, 1045 insertions(+), 302 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodParser.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodParser.java b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodParser.java
index 58ada5a..0e839df 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodParser.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodParser.java
@@ -178,10 +178,14 @@ public abstract class ApiMethodParser<T> {
     }
 
     protected Class<?> forName(String className) {
-        return forName(className, classLoader);
+        try {
+            return forName(className, classLoader);
+        } catch (ClassNotFoundException e1) {
+            throw new IllegalArgumentException("Error loading class " + className);
+        }
     }
 
-    public static Class<?> forName(String className, ClassLoader classLoader) {
+    public static Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
         Class<?> result;
         try {
             // lookup primitive types first
@@ -196,12 +200,8 @@ public abstract class ApiMethodParser<T> {
                 final int nDimensions = (className.length() - firstDim) / 2;
                 return Array.newInstance(forName(className.substring(0, firstDim), classLoader), new int[nDimensions]).getClass();
             }
-            try {
-                // try loading from default Java package java.lang
-                result = Class.forName(JAVA_LANG + className, true, classLoader);
-            } catch (ClassNotFoundException e1) {
-                throw new IllegalArgumentException("Error loading class " + className);
-            }
+            // try loading from default Java package java.lang
+            result = Class.forName(JAVA_LANG + className, true, classLoader);
         }
 
         return result;

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/pom.xml b/tooling/maven/camel-component-util-maven-plugin/pom.xml
index d6159f1..350cd08 100644
--- a/tooling/maven/camel-component-util-maven-plugin/pom.xml
+++ b/tooling/maven/camel-component-util-maven-plugin/pom.xml
@@ -60,6 +60,13 @@
       <artifactId>velocity</artifactId>
       <version>${velocity-version}</version>
     </dependency>
+<!--
+    <dependency>
+      <groupId>net.sourceforge.htmlunit</groupId>
+      <artifactId>htmlunit</artifactId>
+      <version>2.14</version>
+    </dependency>
+-->
 
     <!-- add some logging to the classpath -->
     <dependency>
@@ -76,6 +83,14 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <!-- VelocityEngine javadoc for testing -->
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity</artifactId>
+      <version>${velocity-version}</version>
+      <classifier>javadoc</classifier>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
new file mode 100644
index 0000000..856a286
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
@@ -0,0 +1,117 @@
+/**
+ * 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.util.List;
+
+import org.apache.camel.util.component.ApiMethodParser;
+import org.apache.camel.util.component.ArgumentSubstitutionParser;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.velocity.VelocityContext;
+
+/**
+ * Base Mojo class for ApiMethod generators.
+ */
+public abstract class AbstractApiMethodGeneratorMojo extends AbstractGeneratorMojo {
+
+    @Parameter(required = true, property = PREFIX + "proxyClass")
+    protected String proxyClass;
+
+    @Parameter(property = PREFIX + "substitutions")
+    protected Substitution[] substitutions = new Substitution[0];
+
+    // cached fields
+    private Class<?> proxyType;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+
+        // load proxy class and get enumeration file to generate
+        final Class proxyType = getProxyType();
+
+        // create parser
+        ApiMethodParser parser = createAdapterParser(proxyType);
+        parser.setSignatures(getSignatureList());
+        parser.setClassLoader(getProjectClassLoader());
+
+        // parse signatures
+        final List<ApiMethodParser.ApiMethodModel> models = parser.parse();
+
+        // generate enumeration from model
+        mergeTemplate(getApiMethodContext(models), getApiMethodFile(), "/api-method-enum.vm");
+    }
+
+    protected ApiMethodParser createAdapterParser(Class proxyType) {
+        return new ArgumentSubstitutionParser(proxyType, getArgumentSubstitutions()){};
+    }
+
+    private VelocityContext getApiMethodContext(List<ApiMethodParser.ApiMethodModel> models) throws MojoExecutionException {
+        VelocityContext context = new VelocityContext();
+        context.put("packageName", outPackage);
+        context.put("enumName", getEnumName());
+        context.put("models", models);
+        context.put("proxyType", getProxyType());
+        context.put("helper", getClass());
+        return context;
+    }
+
+    public abstract List<String> getSignatureList() throws MojoExecutionException;
+
+    public Class getProxyType() throws MojoExecutionException {
+        if (proxyType == null) {
+            // load proxy class from Project runtime dependencies
+            try {
+                proxyType = getProjectClassLoader().loadClass(proxyClass);
+            } catch (ClassNotFoundException e) {
+                throw new MojoExecutionException(e.getMessage(), e);
+            }
+        }
+        return proxyType;
+    }
+
+    public File getApiMethodFile() throws MojoExecutionException {
+        final StringBuilder fileName = new StringBuilder();
+        fileName.append(outPackage.replaceAll("\\.", File.separator)).append(File.separator);
+        fileName.append(getEnumName()).append(".java");
+        return new File(outDir, fileName.toString());
+    }
+
+    private String getEnumName() throws MojoExecutionException {
+        return getProxyType().getSimpleName() + "ApiMethod";
+    }
+
+    public static String getType(Class<?> clazz) {
+        if (clazz.isArray()) {
+            // create a zero length array and get the class from the instance
+            return "new " + clazz.getCanonicalName().replaceAll("\\[\\]", "[0]") + ".getClass()";
+        } else {
+            return clazz.getCanonicalName() + ".class";
+        }
+    }
+
+    public ArgumentSubstitutionParser.Substitution[] getArgumentSubstitutions() {
+        ArgumentSubstitutionParser.Substitution[] subs = new ArgumentSubstitutionParser.Substitution[substitutions.length];
+        for (int i = 0; i < substitutions.length; i++) {
+            subs[i] = new ArgumentSubstitutionParser.Substitution(substitutions[i].getMethod(),
+                    substitutions[i].getArgName(), substitutions[i].getArgType(), substitutions[i].getReplacement());
+        }
+        return subs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractGeneratorMojo.java
new file mode 100644
index 0000000..0e29a96
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/AbstractGeneratorMojo.java
@@ -0,0 +1,137 @@
+/**
+ * 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.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.log4j.Logger;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.runtime.RuntimeConstants;
+import org.apache.velocity.runtime.log.Log4JLogChute;
+import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
+
+/**
+ * Base class for Api based code generation MOJOs.
+ */
+public abstract class AbstractGeneratorMojo extends AbstractMojo {
+
+    protected static final String PREFIX = "org.apache.camel.";
+    protected static final String OUT_PACKAGE = PREFIX + "component";
+
+
+    // used for velocity logging, to avoid creating velocity.log
+    protected final Logger LOG = Logger.getLogger(this.getClass());
+
+    @Parameter(defaultValue = "${project}", readonly = true)
+    MavenProject project;
+
+    @Parameter(defaultValue = "${project.build.directory}/generated-sources/camel")
+    protected File outDir;
+
+    @Parameter(defaultValue = OUT_PACKAGE)
+    protected String outPackage;
+
+    private VelocityEngine engine;
+    private ClassLoader projectClassLoader;
+
+    public void setEngine(VelocityEngine engine) {
+        this.engine = engine;
+    }
+
+    public VelocityEngine getEngine() {
+        if (engine == null) {
+            // initialize velocity to load resources from class loader and use Log4J
+            Properties velocityProperties = new Properties();
+            velocityProperties.setProperty(RuntimeConstants.RESOURCE_LOADER, "cloader");
+            velocityProperties.setProperty("cloader.resource.loader.class", ClasspathResourceLoader.class.getName());
+            velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
+            velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM + ".log4j.logger", LOG.getName());
+            engine = new VelocityEngine(velocityProperties);
+            engine.init();
+        }
+        return engine;
+    }
+
+    protected void setProjectClassLoader(ClassLoader projectClassLoader) {
+        this.projectClassLoader = projectClassLoader;
+    }
+
+    protected ClassLoader getProjectClassLoader() throws MojoExecutionException {
+        if (projectClassLoader == null)  {
+            final List classpathElements;
+            try {
+                classpathElements = project.getRuntimeClasspathElements();
+            } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
+                throw new MojoExecutionException(e.getMessage(), e);
+            }
+            final URL[] urls = new URL[classpathElements.size()];
+            int i = 0;
+            for (Iterator it = classpathElements.iterator(); it.hasNext(); i++) {
+                try {
+                    urls[i] = new File((String) it.next()).toURI().toURL();
+                } catch (MalformedURLException e) {
+                    throw new MojoExecutionException(e.getMessage(), e);
+                }
+            }
+            final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+            projectClassLoader = new URLClassLoader(urls, tccl != null ? tccl : getClass().getClassLoader());
+        }
+        return projectClassLoader;
+    }
+
+    protected void mergeTemplate(VelocityContext context, File outFile, String templateName) throws MojoExecutionException {
+        // ensure parent directories exist
+        outFile.getParentFile().mkdirs();
+
+        // add generated date
+        context.put("generatedDate", new Date().toString());
+
+        // load velocity template
+        final Template template = getEngine().getTemplate(templateName, "UTF-8");
+
+        // generate file
+        BufferedWriter writer = null;
+        try {
+            writer = new BufferedWriter(new FileWriter(outFile));
+            template.merge(context, writer);
+        } catch (IOException e) {
+            throw new MojoExecutionException(e.getMessage(), e);
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException ignore) {}
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
new file mode 100644
index 0000000..7a90b81
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
@@ -0,0 +1,109 @@
+/**
+ * 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 org.apache.maven.plugin.AbstractMojoExecutionException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.velocity.VelocityContext;
+
+/**
+ * Generates Camel Component based on a collection of APIs.
+ */
+@Mojo(name = "fromApis", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresProject = true,
+        defaultPhase = LifecyclePhase.GENERATE_SOURCES)
+public class ApiComponentGeneratorMojo extends AbstractGeneratorMojo {
+
+    @Parameter(required = true)
+    protected String componentName;
+
+    @Parameter(required = true)
+    protected ApiProxy[] apis;
+
+    @Override
+    public void execute() throws MojoExecutionException, MojoFailureException {
+        if (apis == null || apis.length == 0) {
+            throw new MojoExecutionException("One or more API proxies are required");
+        }
+
+        // generate ApiMethods
+        for (int i = 0; i < apis.length; i++) {
+            apis[i].validate();
+
+            AbstractApiMethodGeneratorMojo generator;
+            if (apis[i].getSignatureFile() != null) {
+                generator = new FileApiMethodGeneratorMojo();
+                ((FileApiMethodGeneratorMojo)generator).signatureFile = apis[i].getSignatureFile();
+            } else {
+                generator = new JavadocApiMethodGeneratorMojo();
+                ((JavadocApiMethodGeneratorMojo)generator).excludePackages = apis[i].getExcludePackages();
+                ((JavadocApiMethodGeneratorMojo)generator).excludeClasses = apis[i].getExcludeClasses();
+            }
+            // set API properties
+            generator.proxyClass = apis[i].getProxyClass();
+            generator.substitutions = apis[i].getSubstitutions();
+            // set shared properties
+            generator.outDir = outDir;
+            generator.outPackage = outPackage;
+            // set shared state
+            generator.setEngine(getEngine());
+            generator.setProjectClassLoader(getProjectClassLoader());
+
+            try {
+                generator.execute();
+            } catch (AbstractMojoExecutionException e) {
+                throw new MojoExecutionException("Error generating ApiMethod for " +
+                        apis[i].getProxyClass() + ": " + e.getMessage(), e);
+            }
+        }
+
+        // TODO generate Component classes
+        // generate ApiCollection
+        mergeTemplate(getApiCollectionContext(), getApiCollectionFile(), "/api-collection.vm");
+    }
+
+    private VelocityContext getApiCollectionContext() {
+        final VelocityContext context = new VelocityContext();
+        context.put("componentName", componentName);
+        context.put("collectionName", getApiCollectionName());
+        context.put("packageName", outPackage);
+        context.put("apis", apis);
+        context.put("helper", getClass());
+        return context;
+    }
+
+    private File getApiCollectionFile() {
+        final StringBuilder fileName = new StringBuilder();
+        fileName.append(outPackage.replaceAll("\\.", File.separator)).append(File.separator);
+        fileName.append(getApiCollectionName()).append(".java");
+        return new File(outDir, fileName.toString());
+    }
+
+    private String getApiCollectionName() {
+        return componentName + "ApiCollection";
+    }
+
+    public static String getApiMethod(String proxyClass) {
+        return proxyClass.substring(proxyClass.lastIndexOf('.') + 1) + "ApiMethod";
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiMethodGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiMethodGeneratorMojo.java
deleted file mode 100644
index ff0d7f9..0000000
--- a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiMethodGeneratorMojo.java
+++ /dev/null
@@ -1,197 +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.maven;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import org.apache.camel.util.component.ApiMethodParser;
-import org.apache.log4j.Logger;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.project.MavenProject;
-import org.apache.velocity.Template;
-import org.apache.velocity.VelocityContext;
-import org.apache.velocity.app.VelocityEngine;
-import org.apache.velocity.runtime.RuntimeConstants;
-import org.apache.velocity.runtime.log.Log4JLogChute;
-import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
-
-/**
- * Base Mojo class for ApiMethod generators.
- */
-public abstract class ApiMethodGeneratorMojo extends AbstractMojo {
-
-    protected static final String PREFIX = "camel.component.util.";
-
-    // used for velocity logging, to avoid creating velocity.log
-    private final Logger LOG = Logger.getLogger(this.getClass());
-
-    @Parameter(defaultValue = "${project}", readonly = true)
-    MavenProject project;
-
-    @Parameter(defaultValue = "${project.build.directory}/generated-sources/camelComponent")
-    protected File outDir;
-
-    @Parameter(defaultValue = "org.apache.camel.util.component")
-    protected String outPackage;
-
-    @Parameter(required = true, property = PREFIX + "proxyClass")
-    protected String proxyClass;
-
-    // cached fields
-    private Class<?> proxyType;
-    private ClassLoader projectClassLoader;
-    private VelocityEngine engine;
-
-    @Override
-    public void execute() throws MojoExecutionException, MojoFailureException {
-
-        // initialize velocity
-        initVelocityEngine();
-
-        // load proxy class and get enumeration file to generate
-        final Class proxyType = getProxyType();
-
-        // create parser
-        ApiMethodParser parser = createAdapterParser(proxyType);
-        parser.setSignatures(getSignatureList());
-        parser.setClassLoader(getProjectClassLoader());
-
-        // parse signatures
-        final List<ApiMethodParser.ApiMethodModel> models = parser.parse();
-
-        // generate enumeration from model
-        generateEnum(models);
-    }
-
-    protected ApiMethodParser createAdapterParser(Class proxyType) {
-        return new ApiMethodParser(proxyType){};
-    }
-
-    private void initVelocityEngine() {
-        // initialize velocity to load resources from class loader and use Log4J
-        Properties velocityProperties = new Properties();
-        velocityProperties.setProperty(RuntimeConstants.RESOURCE_LOADER, "cloader");
-        velocityProperties.setProperty("cloader.resource.loader.class", ClasspathResourceLoader.class.getName());
-        velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, Log4JLogChute.class.getName());
-        velocityProperties.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM + ".log4j.logger", LOG.getName());
-        engine = new VelocityEngine(velocityProperties);
-        engine.init();
-    }
-
-    private void generateEnum(List<ApiMethodParser.ApiMethodModel> models) throws MojoExecutionException {
-        final File apiMethodFile = getApiMethodFile();
-        // ensure parent directories exist
-        apiMethodFile.getParentFile().mkdirs();
-
-        // set template parameters
-        VelocityContext context = new VelocityContext();
-        context.put("generatedDate", new Date().toString());
-        context.put("packageName", outPackage);
-        context.put("enumName", getEnumName());
-        context.put("models", models);
-        context.put("proxyType", getProxyType());
-        context.put("helper", getClass());
-
-        // load velocity template
-        final Template template = engine.getTemplate("/api-method-enum.vm", "UTF-8");
-
-        // generate Enumeration
-        BufferedWriter writer = null;
-        try {
-            writer = new BufferedWriter(new FileWriter(apiMethodFile));
-            template.merge(context, writer);
-        } catch (IOException e) {
-            throw new MojoExecutionException(e.getMessage(), e);
-        } finally {
-            if (writer != null) {
-                try {
-                    writer.close();
-                } catch (IOException ignore) {}
-            }
-        }
-    }
-
-    public abstract List<String> getSignatureList() throws MojoExecutionException;
-
-    public Class getProxyType() throws MojoExecutionException {
-        if (proxyType == null) {
-            // load proxy class from Project runtime dependencies
-            try {
-                proxyType = getProjectClassLoader().loadClass(proxyClass);
-            } catch (ClassNotFoundException e) {
-                throw new MojoExecutionException(e.getMessage(), e);
-            }
-        }
-        return proxyType;
-    }
-
-    private ClassLoader getProjectClassLoader() throws MojoExecutionException {
-        if (projectClassLoader == null)  {
-            final List classpathElements;
-            try {
-                classpathElements = project.getRuntimeClasspathElements();
-            } catch (org.apache.maven.artifact.DependencyResolutionRequiredException e) {
-                throw new MojoExecutionException(e.getMessage(), e);
-            }
-            final URL[] urls = new URL[classpathElements.size()];
-            int i = 0;
-            for (Iterator it = classpathElements.iterator(); it.hasNext(); i++) {
-                try {
-                    urls[i] = new File((String) it.next()).toURI().toURL();
-                } catch (MalformedURLException e) {
-                    throw new MojoExecutionException(e.getMessage(), e);
-                }
-            }
-            projectClassLoader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());
-        }
-        return projectClassLoader;
-    }
-
-    public File getApiMethodFile() throws MojoExecutionException {
-        final StringBuilder fileName = new StringBuilder();
-        fileName.append(outPackage.replaceAll("\\.", File.separator)).append(File.separator);
-        fileName.append(getEnumName()).append(".java");
-        return new File(outDir, fileName.toString());
-    }
-
-    private String getEnumName() throws MojoExecutionException {
-        return getProxyType().getSimpleName() + "ApiMethod";
-    }
-
-    public static String getType(Class<?> clazz) {
-        if (clazz.isArray()) {
-            // create a zero length array and get the class from the instance
-            return "new " + clazz.getCanonicalName().replaceAll("\\[\\]", "[0]") + ".getClass()";
-        } else {
-            return clazz.getCanonicalName() + ".class";
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiProxy.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiProxy.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiProxy.java
new file mode 100644
index 0000000..54e5b80
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/ApiProxy.java
@@ -0,0 +1,100 @@
+/**
+ * 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.util.Collections;
+import java.util.Map;
+
+/**
+ * Represents an API to use for generating Camel Component.
+ */
+public class ApiProxy {
+    private String apiName;
+    private String proxyClass;
+
+    private Substitution[] substitutions = new Substitution[0];
+
+    private String excludePackages = JavadocApiMethodGeneratorMojo.DEFAULT_EXCLUDE_PACKAGES;
+    private String excludeClasses;
+
+    private File signatureFile;
+
+    private Map<String, String> aliases = Collections.EMPTY_MAP;
+
+    public String getApiName() {
+        return apiName;
+    }
+
+    public void setApiName(String apiName) {
+        this.apiName = apiName;
+    }
+
+    public String getProxyClass() {
+        return proxyClass;
+    }
+
+    public void setProxyClass(String proxyClass) {
+        this.proxyClass = proxyClass;
+    }
+
+    public Substitution[] getSubstitutions() {
+        return substitutions;
+    }
+
+    public void setSubstitutions(Substitution[] substitutions) {
+        this.substitutions = substitutions;
+    }
+
+    public String getExcludePackages() {
+        return excludePackages;
+    }
+
+    public void setExcludePackages(String excludePackages) {
+        this.excludePackages = excludePackages;
+    }
+
+    public String getExcludeClasses() {
+        return excludeClasses;
+    }
+
+    public void setExcludeClasses(String excludeClasses) {
+        this.excludeClasses = excludeClasses;
+    }
+
+    public File getSignatureFile() {
+        return signatureFile;
+    }
+
+    public void setSignatureFile(File signatureFile) {
+        this.signatureFile = signatureFile;
+    }
+
+    public Map<String, String> getAliases() {
+        return aliases;
+    }
+
+    public void setAliases(Map<String, String> aliases) {
+        this.aliases = aliases;
+    }
+
+    public void validate() {
+        if (apiName == null || proxyClass == null) {
+            throw new IllegalArgumentException("Properties apiName and proxyClass are required");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/FileApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/FileApiMethodGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/FileApiMethodGeneratorMojo.java
index 8ce2cf2..566ef0a 100644
--- a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/FileApiMethodGeneratorMojo.java
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/FileApiMethodGeneratorMojo.java
@@ -24,8 +24,6 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.apache.camel.util.component.ApiMethodParser;
-import org.apache.camel.util.component.ArgumentSubstitutionParser;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
@@ -35,30 +33,23 @@ import org.apache.maven.plugins.annotations.ResolutionScope;
 /**
  * Parses ApiMethod signatures from a File.
  */
-@Mojo(name = "fromFile", requiresDependencyResolution = ResolutionScope.RUNTIME, requiresProject = true,
+@Mojo(name = "fromFile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresProject = true,
         defaultPhase = LifecyclePhase.GENERATE_SOURCES)
-public class FileApiMethodGeneratorMojo extends ApiMethodGeneratorMojo {
+public class FileApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMojo {
 
-    @Parameter(required = true, property = "camel.component.util.signatures")
-    protected File signatures;
-
-    @Parameter(property = "camel.component.util.substitutions")
-    protected Substitution[] substitutions;
-
-    @Override
-    protected ApiMethodParser createAdapterParser(Class proxyType) {
-        return new ArgumentSubstitutionParser(proxyType, getArgumentSubstitutions());
-    }
+    @Parameter(required = true, property = PREFIX + "signatureFile")
+    protected File signatureFile;
 
     @Override
     public List<String> getSignatureList() throws MojoExecutionException {
-        // get signatures as a list of Strings
+        // get signatureFile as a list of Strings
         List<String> result = new ArrayList<String>();
         try {
-            BufferedReader reader = new BufferedReader(new FileReader(this.signatures));
+            BufferedReader reader = new BufferedReader(new FileReader(this.signatureFile));
             String line = reader.readLine();
             while (line != null) {
                 result.add(line);
+                line = reader.readLine();
             }
         } catch (FileNotFoundException e) {
             throw new MojoExecutionException(e.getMessage(), e);
@@ -66,17 +57,8 @@ public class FileApiMethodGeneratorMojo extends ApiMethodGeneratorMojo {
             throw new MojoExecutionException(e.getMessage(), e);
         }
         if (result.isEmpty()) {
-            throw new MojoExecutionException("Signature file " + signatures.getPath() + " is empty");
+            throw new MojoExecutionException("Signature file " + signatureFile.getPath() + " is empty");
         }
         return result;
     }
-
-    public ArgumentSubstitutionParser.Substitution[] getArgumentSubstitutions() {
-        ArgumentSubstitutionParser.Substitution[] subs = new ArgumentSubstitutionParser.Substitution[substitutions.length];
-        for (int i = 0; i < substitutions.length; i++) {
-            subs[i] = new ArgumentSubstitutionParser.Substitution(substitutions[i].getMethod(),
-                    substitutions[i].getArgName(), substitutions[i].getArgType(), substitutions[i].getReplacement());
-        }
-        return subs;
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
new file mode 100644
index 0000000..b94aab7
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
@@ -0,0 +1,252 @@
+/**
+ * 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.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import javax.swing.text.ChangedCharSetException;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.parser.DTD;
+import javax.swing.text.html.parser.Parser;
+import javax.swing.text.html.parser.TagElement;
+
+import org.apache.camel.util.component.ApiMethodParser;
+import org.apache.camel.util.component.ArgumentSubstitutionParser;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+/**
+ * Parses ApiMethod signatures from Javadoc.
+ */
+@Mojo(name = "fromJavaDoc", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, requiresProject = true,
+        defaultPhase = LifecyclePhase.GENERATE_SOURCES)
+public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMojo {
+
+    protected static final String DEFAULT_EXCLUDE_PACKAGES = "javax?\\.lang.*";
+
+    @Parameter(property = "camel.component.util.excludePackages", defaultValue = DEFAULT_EXCLUDE_PACKAGES)
+    protected String excludePackages;
+
+    @Parameter(property = "camel.component.util.excludeClasses")
+    protected String excludeClasses;
+
+    @Override
+    protected ApiMethodParser createAdapterParser(Class proxyType) {
+        return new ArgumentSubstitutionParser(proxyType, getArgumentSubstitutions());
+    }
+
+    @Override
+    public List<String> getSignatureList() throws MojoExecutionException {
+        // get signatures as a list of Strings
+        List<String> result = new ArrayList<String>();
+
+        final Pattern packages = Pattern.compile(excludePackages);
+        Pattern classes = null;
+        if (excludeClasses != null) {
+            classes = Pattern.compile(excludeClasses);
+        }
+
+        // for proxy class and super classes not matching excluded packages or classes
+        for (Class aClass = getProxyType();
+             !packages.matcher(aClass.getPackage().getName()).matches() && (classes == null ||
+                     !classes.matcher(aClass.getSimpleName()).matches()); aClass = aClass.getSuperclass()) {
+
+            final String javaDocPath = aClass.getName().replaceAll("\\.", "/") + ".html";
+
+            // read javadoc html text for class
+            try {
+                final InputStream inputStream = getProjectClassLoader().getResourceAsStream(javaDocPath);
+                if (inputStream == null) {
+                    throw new MojoExecutionException("JavaDoc not found using classpath for " + aClass.getName());
+                }
+                // transform the HTML to get method summary as text
+                // dummy DTD
+                final DTD dtd = DTD.getDTD("html.dtd");
+                final JavadocParser htmlParser = new JavadocParser(dtd, javaDocPath);
+                htmlParser.parse(new InputStreamReader(inputStream, "UTF-8"));
+
+                // get public method signature
+                final Map<String, String> methodMap = htmlParser.getMethodText();
+                for (String method : htmlParser.getMethods()) {
+                    final int leftBracket = method.indexOf('(');
+                    final String name = method.substring(0, leftBracket);
+                    final String args = method.substring(leftBracket + 1, method.length() - 1);
+                    String[] types;
+                    if (args.isEmpty()) {
+                        types = new String[0];
+                    } else {
+                        types = args.split(",");
+                    }
+                    final String resultType = getResultType(aClass, name, types);
+                    if (resultType != null) {
+                        final StringBuilder signature = new StringBuilder(resultType);
+                        signature.append(" ").append(name).append(methodMap.get(method));
+                        result.add(signature.toString());
+                    }
+                }
+            } catch (IOException e) {
+                throw new MojoExecutionException(e.getMessage(), e);
+            }
+        }
+
+        return result;
+    }
+
+    private String getResultType(Class<?> aClass, String name, String[] types) throws MojoExecutionException {
+        Class<?>[] argTypes = new Class<?>[types.length];
+        final ClassLoader classLoader = getProjectClassLoader();
+        for (int i = 0; i < types.length; i++) {
+            try {
+                try {
+                    argTypes[i] = ApiMethodParser.forName(types[i].trim(), classLoader);
+                } catch (ClassNotFoundException e) {
+                    throw new MojoExecutionException(e.getMessage(), e);
+                }
+            } catch (IllegalArgumentException e) {
+                throw new MojoExecutionException(e.getCause().getMessage(), e.getCause());
+            }
+        }
+        try {
+            final Method method = aClass.getMethod(name, argTypes);
+            if ((method.getModifiers() & Modifier.PUBLIC) != 0) {
+                return method.getReturnType().getCanonicalName();
+            } else {
+                return null;
+            }
+        } catch (NoSuchMethodException e) {
+            throw new MojoExecutionException(e.getMessage(), e);
+        }
+    }
+
+    private class JavadocParser extends Parser {
+        private String hrefPattern;
+
+        private ParserState parserState;
+        private String methodWithTypes;
+        private StringBuilder methodTextBuilder = new StringBuilder();
+
+        private List<String> methods = new ArrayList<String>();
+        private Map<String, String> methodText = new HashMap<String, String>();
+
+        public JavadocParser(DTD dtd, String docPath) {
+            super(dtd);
+            this.hrefPattern = docPath + "#";
+        }
+
+        @Override
+        protected void startTag(TagElement tag) throws ChangedCharSetException {
+            super.startTag(tag);
+
+            final HTML.Tag htmlTag = tag.getHTMLTag();
+            if (htmlTag != null) {
+                if (HTML.Tag.A.equals(htmlTag)) {
+                    final SimpleAttributeSet attributes = getAttributes();
+                    final Object name = attributes.getAttribute(HTML.Attribute.NAME);
+                    if (name != null) {
+                        final String nameAttr = (String) name;
+                        if (parserState == null && "method_summary".equals(nameAttr)) {
+                            parserState = ParserState.METHOD_SUMMARY;
+                        } else if (parserState == ParserState.METHOD_SUMMARY && nameAttr.startsWith("methods_inherited_from_class_")) {
+                            parserState = null;
+                        } else if (parserState == ParserState.METHOD && methodWithTypes == null) {
+                            final Object href = attributes.getAttribute(HTML.Attribute.HREF);
+                            if (href != null) {
+                                String hrefAttr = (String) href;
+                                if (hrefAttr.contains(hrefPattern)) {
+                                    methodWithTypes = hrefAttr.substring(hrefAttr.indexOf('#') + 1);
+                                }
+                            }
+                        }
+                    }
+                } else if (parserState == ParserState.METHOD_SUMMARY && HTML.Tag.CODE.equals(htmlTag)) {
+                    parserState = ParserState.METHOD;
+                }
+            }
+        }
+
+        @Override
+        protected void endTag(boolean omitted) {
+            super.endTag(omitted);    //To change body of overridden methods use File | Settings | File Templates.
+        }
+
+        @Override
+        protected void handleEmptyTag(TagElement tag) {
+            if (parserState == ParserState.METHOD && HTML.Tag.CODE.equals(tag.getHTMLTag())) {
+                if (methodWithTypes != null) {
+                    // process collected method data
+                    methods.add(methodWithTypes);
+                    this.methodText.put(methodWithTypes, getArgSignature());
+
+                    // clear the text builder for next method
+                    methodTextBuilder.delete(0, methodTextBuilder.length());
+                    methodWithTypes = null;
+                }
+
+                parserState = ParserState.METHOD_SUMMARY;
+            }
+        }
+
+        private String getArgSignature() {
+            final String typeString = methodWithTypes.substring(methodWithTypes.indexOf('(') + 1, methodWithTypes.indexOf(')'));
+            if (typeString.isEmpty()) {
+                return "()";
+            }
+            final String[] types = typeString.split(",");
+            String argText = methodTextBuilder.toString().replaceAll("&nbsp;", " ").replaceAll("&nbsp", " ");
+            final String[] args = argText.substring(argText.indexOf('(') + 1, argText.indexOf(')')).split(",");
+            StringBuilder builder = new StringBuilder("(");
+            for (int i = 0; i < types.length; i++) {
+                final String[] arg = args[i].trim().split(" ");
+                builder.append(types[i]).append(" ").append(arg[1].trim()).append(",");
+            }
+            builder.deleteCharAt(builder.length() - 1);
+            builder.append(")");
+            return builder.toString();
+        }
+
+        @Override
+        protected void handleText(char[] text) {
+            if (parserState == ParserState.METHOD && methodWithTypes != null) {
+                methodTextBuilder.append(text);
+            }
+        }
+
+        private List<String> getMethods() {
+            return methods;
+        }
+
+        private Map<String, String> getMethodText() {
+            return methodText;
+        }
+    }
+
+    private static enum ParserState {
+        METHOD_SUMMARY, METHOD;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/main/resources/api-collection.vm
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/main/resources/api-collection.vm b/tooling/maven/camel-component-util-maven-plugin/src/main/resources/api-collection.vm
new file mode 100644
index 0000000..26382db
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/main/resources/api-collection.vm
@@ -0,0 +1,46 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+## api-collection.vm
+/*
+ * Camel ApiCollection generated by camel-component-util-maven-plugin
+ * Generated on: $generatedDate
+ */
+package $packageName;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.camel.util.component.ApiCollection;
+import org.apache.camel.util.component.ApiMethodHelper;
+
+/**
+ * Camel {@link ApiCollection} for $componentName
+ */
+public class $collectionName extends ApiCollection {
+
+    public ${collectionName}() {
+        final Map<String, String> aliases = new HashMap<String, String>();
+#foreach( $api in $apis )
+        aliases.clear();
+#foreach( $alias in $api.Aliases.entrySet() )
+        aliases.put("$alias.Key", "$alias.Value");
+#end
+#set( $apiMethod = $helper.getApiMethod($api.ProxyClass) )
+        apis.put("$api.ApiName", new ApiMethodHelper<$apiMethod>(${apiMethod}.class, aliases));
+#end
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/AbstractGeneratorMojoTest.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/AbstractGeneratorMojoTest.java b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/AbstractGeneratorMojoTest.java
new file mode 100644
index 0000000..eaaf704
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/AbstractGeneratorMojoTest.java
@@ -0,0 +1,35 @@
+/**
+ * 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 static org.junit.Assert.assertTrue;
+
+/**
+ * User: dbokde
+ * Date: 5/26/14
+ * Time: 4:49 AM
+ */
+public class AbstractGeneratorMojoTest {
+    protected static final String OUT_DIR = "target/generated-test-sources/camelComponent";
+    protected static final String PACKAGE_PATH = AbstractGeneratorMojo.OUT_PACKAGE.replaceAll("\\.", "/");
+
+    protected void assertExists(File outFile) {
+        assertTrue("Generated file not found " + outFile.getPath(), outFile.exists());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiComponentGeneratorMojoTest.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiComponentGeneratorMojoTest.java b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiComponentGeneratorMojoTest.java
new file mode 100644
index 0000000..3176755
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiComponentGeneratorMojoTest.java
@@ -0,0 +1,78 @@
+/**
+ * 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.util.Collections;
+import java.util.List;
+
+import org.apache.camel.util.FileUtil;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.model.Model;
+import org.apache.maven.project.MavenProject;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link ApiComponentGeneratorMojo}
+ */
+public class ApiComponentGeneratorMojoTest extends AbstractGeneratorMojoTest {
+
+    private static final String COMPONENT_NAME = "TestComponent";
+
+    @Test
+    public void testExecute() throws Exception {
+
+        // delete target files to begin
+        final File outDir = new File(OUT_DIR);
+        FileUtil.removeDir(outDir);
+
+        final File collectionFile = new File(OUT_DIR, PACKAGE_PATH + "/" + COMPONENT_NAME + "ApiCollection.java");
+
+        final ApiComponentGeneratorMojo mojo = new ApiComponentGeneratorMojo();
+        mojo.componentName = COMPONENT_NAME;
+        mojo.outDir = new File(OUT_DIR);
+        mojo.outPackage = AbstractGeneratorMojo.OUT_PACKAGE;
+        mojo.project = new MavenProject((Model) null) {
+            @Override
+            public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException {
+                return Collections.EMPTY_LIST;
+            }
+        };
+
+        final ApiProxy[] proxies = new ApiProxy[2];
+        mojo.apis = proxies;
+        ApiProxy apiProxy = new ApiProxy();
+        proxies[0] = apiProxy;
+        apiProxy.setApiName("test");
+        apiProxy.setProxyClass(TestProxy.class.getName());
+        apiProxy.setSignatureFile(new File("src/test/resources/test-proxy-signatures.txt"));
+        Substitution[] substitutions = new Substitution[1];
+        substitutions[0] = new Substitution(".+", "(.+)", "java.util.List", "$1List");
+        apiProxy.setSubstitutions(substitutions);
+
+        apiProxy = new ApiProxy();
+        proxies[1] = apiProxy;
+        apiProxy.setApiName("velocity");
+        apiProxy.setProxyClass(VelocityEngine.class.getName());
+
+        mojo.execute();
+
+        // check target file was generated
+        assertExists(collectionFile);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiMethodEnumTest.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiMethodEnumTest.java b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiMethodEnumTest.java
deleted file mode 100644
index b224a6e..0000000
--- a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/ApiMethodEnumTest.java
+++ /dev/null
@@ -1,71 +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.maven;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.model.Model;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.project.MavenProject;
-import org.junit.Test;
-
-/**
- * Tests api-method-enum.vm
- */
-public class ApiMethodEnumTest {
-
-    @Test
-    public void testTemplate() throws IOException, MojoFailureException, MojoExecutionException {
-
-        final FileApiMethodGeneratorMojo mojo = new FileApiMethodGeneratorMojo() {
-
-            @Override
-            public List<String> getSignatureList() throws MojoExecutionException {
-                final ArrayList<String> signatures = new ArrayList<String>();
-                signatures.add("public String sayHi();");
-                signatures.add("public String sayHi(final String name);");
-                signatures.add("public final String greetMe(final String name);");
-                signatures.add("public final String greetUs(final String name1, String name2);");
-                signatures.add("public final String greetAll(String[] names);");
-                signatures.add("public final String greetAll(java.util.List<String> names);");
-                signatures.add("public final String[] greetTimes(String name, int times);");
-                return signatures;
-            }
-        };
-        mojo.substitutions = new Substitution[1];
-        mojo.substitutions[0] = new Substitution(".+", "(.+)", "java.util.List", "$1List");
-
-        mojo.outDir = new File("target/generated-test-sources/camelComponent");
-        mojo.outPackage = "org.apache.camel.component.util";
-        mojo.proxyClass = TestProxy.class.getCanonicalName();
-        mojo.project = new MavenProject((Model) null) {
-            @Override
-            public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException {
-                return Collections.EMPTY_LIST;
-            }
-        };
-
-        mojo.execute();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/FileApiMethodGeneratorMojoTest.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/FileApiMethodGeneratorMojoTest.java b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/FileApiMethodGeneratorMojoTest.java
new file mode 100644
index 0000000..7f9661e
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/FileApiMethodGeneratorMojoTest.java
@@ -0,0 +1,67 @@
+/**
+ * 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.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests {@link FileApiMethodGeneratorMojo}
+ */
+public class FileApiMethodGeneratorMojoTest extends AbstractGeneratorMojoTest {
+
+    @Test
+    public void testExecute() throws IOException, MojoFailureException, MojoExecutionException {
+
+        // delete target file to begin
+        final File outFile = new File(OUT_DIR, PACKAGE_PATH + "/TestProxyApiMethod.java");
+        if (outFile.exists()) {
+            outFile.delete();
+        }
+
+        final FileApiMethodGeneratorMojo mojo = new FileApiMethodGeneratorMojo();
+        mojo.substitutions = new Substitution[1];
+        mojo.substitutions[0] = new Substitution(".+", "(.+)", "java.util.List", "$1List");
+
+        mojo.outDir = new File(OUT_DIR);
+        mojo.outPackage = AbstractGeneratorMojo.OUT_PACKAGE;
+        mojo.proxyClass = TestProxy.class.getCanonicalName();
+        mojo.project = new MavenProject((Model) null) {
+            @Override
+            public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException {
+                return Collections.EMPTY_LIST;
+            }
+        };
+        mojo.signatureFile = new File("src/test/resources/test-proxy-signatures.txt");
+
+        mojo.execute();
+
+        // check target file was generated
+        assertTrue("Generated file not found " + outFile.getPath(), outFile.exists());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojoTest.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojoTest.java b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojoTest.java
new file mode 100644
index 0000000..8ac2d46
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/test/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojoTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link JavadocApiMethodGeneratorMojo}
+ */
+public class JavadocApiMethodGeneratorMojoTest extends AbstractGeneratorMojoTest {
+
+    @Test
+    public void testExecute() throws IOException, MojoFailureException, MojoExecutionException {
+
+        // delete target file to begin
+        final File outFile = new File(OUT_DIR, AbstractGeneratorMojo.OUT_PACKAGE.replaceAll("\\.", "/") + "/VelocityEngineApiMethod.java");
+        if (outFile.exists()) {
+            outFile.delete();
+        }
+
+        final JavadocApiMethodGeneratorMojo mojo = new JavadocApiMethodGeneratorMojo();
+
+        mojo.outDir = new File(OUT_DIR);
+        mojo.outPackage = AbstractGeneratorMojo.OUT_PACKAGE;
+        // use VelocityEngine javadoc
+        mojo.proxyClass = VelocityEngine.class.getCanonicalName();
+        mojo.project = new MavenProject((Model) null) {
+            @Override
+            public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException {
+                return Collections.EMPTY_LIST;
+            }
+        };
+        mojo.excludePackages = JavadocApiMethodGeneratorMojo.DEFAULT_EXCLUDE_PACKAGES;
+
+        mojo.execute();
+
+        // check target file was generated
+        assertExists(outFile);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/ecee7f1f/tooling/maven/camel-component-util-maven-plugin/src/test/resources/test-proxy-signatures.txt
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-component-util-maven-plugin/src/test/resources/test-proxy-signatures.txt b/tooling/maven/camel-component-util-maven-plugin/src/test/resources/test-proxy-signatures.txt
new file mode 100644
index 0000000..1d5ba35
--- /dev/null
+++ b/tooling/maven/camel-component-util-maven-plugin/src/test/resources/test-proxy-signatures.txt
@@ -0,0 +1,7 @@
+public String sayHi();
+public String sayHi(final String name);
+public final String greetMe(final String name);
+public final String greetUs(final String name1, String name2);
+public final String greetAll(String[] names);
+public final String greetAll(java.util.List<String> names);
+public final String[] greetTimes(String name, int times);