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/20 23:09:32 UTC

[1/2] git commit: Fixed JavadocApiMethodGeneratorMojo to support multiple type arguments, added includeStaticMethods parameter to support adding static method to API model

Repository: camel
Updated Branches:
  refs/heads/master 7616b4356 -> f6114d52d


Fixed JavadocApiMethodGeneratorMojo to support multiple type arguments, added includeStaticMethods parameter to support adding static method to API model


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

Branch: refs/heads/master
Commit: f6114d52de9a037a7bc530d4f7d0c260a371e00a
Parents: 909077a
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Jun 20 14:05:43 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Jun 20 14:09:20 2014 -0700

----------------------------------------------------------------------
 .../__artifactId__-component/pom.xml            |  1 +
 .../maven/AbstractApiMethodGeneratorMojo.java   |  3 +-
 .../camel/maven/ApiComponentGeneratorMojo.java  |  2 +
 .../org/apache/camel/maven/FromJavadoc.java     | 10 +++
 .../maven/JavadocApiMethodGeneratorMojo.java    | 65 +++++++++++++++-----
 5 files changed, 66 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/f6114d52/tooling/archetypes/camel-archetype-api-component/src/main/resources/archetype-resources/__artifactId__-component/pom.xml
----------------------------------------------------------------------
diff --git a/tooling/archetypes/camel-archetype-api-component/src/main/resources/archetype-resources/__artifactId__-component/pom.xml b/tooling/archetypes/camel-archetype-api-component/src/main/resources/archetype-resources/__artifactId__-component/pom.xml
index f86474d..b605a57 100644
--- a/tooling/archetypes/camel-archetype-api-component/src/main/resources/archetype-resources/__artifactId__-component/pom.xml
+++ b/tooling/archetypes/camel-archetype-api-component/src/main/resources/archetype-resources/__artifactId__-component/pom.xml
@@ -202,6 +202,7 @@
                     <excludePackages>package-name-patterns</excludePackages>
                     <excludeClasses>class-name-patterns</excludeClasses>
                     <excludeMethods>method-name-patterns</excludeMethods>
+                    <includeStaticMethods>use 'true' to include static methods, false by default<includeStaticMethods>
                     -->
                   </fromJavadoc>
                 </api>

http://git-wip-us.apache.org/repos/asf/camel/blob/f6114d52/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
index 3cb3e8f..ec17364 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/AbstractApiMethodGeneratorMojo.java
@@ -97,7 +97,7 @@ public abstract class AbstractApiMethodGeneratorMojo extends AbstractApiMethodBa
 
     public abstract List<String> getSignatureList() throws MojoExecutionException;
 
-    public Class getProxyType() throws MojoExecutionException {
+    public Class<?> getProxyType() throws MojoExecutionException {
         if (proxyType == null) {
             // load proxy class from Project runtime dependencies
             try {
@@ -290,6 +290,7 @@ public abstract class AbstractApiMethodGeneratorMojo extends AbstractApiMethodBa
             StringBuilder parameterizedType = new StringBuilder(canonicalName);
             parameterizedType.append('<');
 
+            // Note: its ok to split, since we don't support parsing nested type arguments
             String[] argTypes = typeArgs.split(",");
             boolean ignore = false;
             for (String argType : argTypes) {

http://git-wip-us.apache.org/repos/asf/camel/blob/f6114d52/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
index c924cdf..dabdcd5 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/ApiComponentGeneratorMojo.java
@@ -163,6 +163,8 @@ public class ApiComponentGeneratorMojo extends AbstractApiMethodBaseMojo {
                     apiFromJavadoc.getExcludeClasses() : fromJavadoc.getExcludeClasses();
                 javadocMojo.excludeMethods = apiFromJavadoc.getExcludeMethods() != null ?
                     apiFromJavadoc.getExcludeMethods() : fromJavadoc.getExcludeMethods();
+                javadocMojo.includeStaticMethods = apiFromJavadoc.getIncludeStaticMethods() != null ?
+                    apiFromJavadoc.getIncludeStaticMethods() : fromJavadoc.getIncludeStaticMethods();
 
                 apiMethodGenerator = javadocMojo;
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/f6114d52/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/FromJavadoc.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/FromJavadoc.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/FromJavadoc.java
index fb2ce5f..f23a301 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/FromJavadoc.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/FromJavadoc.java
@@ -27,6 +27,8 @@ public class FromJavadoc {
 
     protected String excludeMethods;
 
+    protected Boolean includeStaticMethods;
+
     public String getExcludePackages() {
         return excludePackages;
     }
@@ -50,4 +52,12 @@ public class FromJavadoc {
     public void setExcludeMethods(String excludeMethods) {
         this.excludeMethods = excludeMethods;
     }
+
+    public Boolean getIncludeStaticMethods() {
+        return includeStaticMethods;
+    }
+
+    public void setIncludeStaticMethods(Boolean includeStaticMethods) {
+        this.includeStaticMethods = includeStaticMethods;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/f6114d52/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
----------------------------------------------------------------------
diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
index 8b02c3e..a8a9beb 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavadocApiMethodGeneratorMojo.java
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import javax.swing.text.ChangedCharSetException;
 import javax.swing.text.SimpleAttributeSet;
@@ -55,6 +56,8 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
     }
 
     protected static final String DEFAULT_EXCLUDE_PACKAGES = "javax?\\.lang.*";
+    private static final Pattern ARGTYPES_PATTERN = Pattern.compile("\\s*([^<\\s,]+\\s*(<[^>]+>)?)\\s*,?");
+    private static final Pattern RAW_ARGTYPES_PATTERN = Pattern.compile("\\s*([^<\\s,]+)\\s*(<[^>]+>)?\\s*,?");
 
     @Parameter(property = PREFIX + "excludePackages", defaultValue = DEFAULT_EXCLUDE_PACKAGES)
     protected String excludePackages;
@@ -65,6 +68,9 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
     @Parameter(property = PREFIX + "excludeMethods")
     protected String excludeMethods;
 
+    @Parameter(property = PREFIX + "includeStaticMethods")
+    protected Boolean includeStaticMethods;
+
     @Override
     public List<String> getSignatureList() throws MojoExecutionException {
         // signatures as map from signature with no arg names to arg names from JavadocParser
@@ -116,7 +122,13 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
                         if (args.isEmpty()) {
                             types = new String[0];
                         } else {
-                            types = args.split(",");
+                            // get raw types from args
+                            final List<String> rawTypes = new ArrayList<String>();
+                            final Matcher argTypesMatcher = RAW_ARGTYPES_PATTERN.matcher(args);
+                            while (argTypesMatcher.find()) {
+                                rawTypes.add(argTypesMatcher.group(1));
+                            }
+                            types = rawTypes.toArray(new String[rawTypes.size()]);
                         }
                         final String resultType = getResultType(aClass, name, types);
                         if (resultType != null) {
@@ -146,7 +158,7 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
         for (int i = 0; i < types.length; i++) {
             try {
                 try {
-                    argTypes[i] = ApiMethodParser.forName(types[i].trim(), classLoader);
+                    argTypes[i] = ApiMethodParser.forName(types[i], classLoader);
                 } catch (ClassNotFoundException e) {
                     throw new MojoExecutionException(e.getMessage(), e);
                 }
@@ -154,13 +166,13 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
                 throw new MojoExecutionException(e.getCause().getMessage(), e.getCause());
             }
         }
-        // return null for non-public and non-static methods
+
+        // return null for non-public methods, and for non-static methods if includeStaticMethods is null or false
         String result = null;
         try {
             final Method method = aClass.getMethod(name, argTypes);
-            // only include non-static public methods
             int modifiers = method.getModifiers();
-            if (!Modifier.isStatic(modifiers)) {
+            if (!Modifier.isStatic(modifiers) || Boolean.TRUE.equals(includeStaticMethods)) {
                 result = method.getReturnType().getCanonicalName();
             }
         } catch (NoSuchMethodException e) {
@@ -175,7 +187,8 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
         return result;
     }
 
-    private class JavadocParser extends Parser {
+    private static class JavadocParser extends Parser {
+        private static final String NON_BREAKING_SPACE = "\u00A0";
         private String hrefPattern;
 
         private ParserState parserState;
@@ -211,7 +224,8 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
                             if (href != null) {
                                 String hrefAttr = (String) href;
                                 if (hrefAttr.contains(hrefPattern)) {
-                                    methodWithTypes = StringEscapeUtils.unescapeHtml(hrefAttr.substring(hrefAttr.indexOf('#') + 1));
+                                    // unescape HTML
+                                    methodWithTypes = unescapeHtml(hrefAttr.substring(hrefAttr.indexOf('#') + 1));
                                 }
                             }
                         }
@@ -222,6 +236,10 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
             }
         }
 
+        private static String unescapeHtml(String htmlString) {
+            return StringEscapeUtils.unescapeHtml(htmlString).replaceAll(NON_BREAKING_SPACE, " ");
+        }
+
         @Override
         protected void handleEmptyTag(TagElement tag) {
             if (parserState == ParserState.METHOD && HTML.Tag.CODE.equals(tag.getHTMLTag())) {
@@ -244,15 +262,34 @@ public class JavadocApiMethodGeneratorMojo extends AbstractApiMethodGeneratorMoj
             if (typeString.isEmpty()) {
                 return "()";
             }
-            final String[] types = typeString.split(",");
-            // use HTTP decode
-            String argText = StringEscapeUtils.unescapeHtml(methodTextBuilder.toString());
-            final String[] args = argText.substring(argText.indexOf('(') + 1, argText.indexOf(')')).split(",");
+
+            // split types list
+            final List<String> typeList = new ArrayList<String>();
+            final Matcher typeMatcher = ARGTYPES_PATTERN.matcher(typeString);
+            while (typeMatcher.find()) {
+                typeList.add(typeMatcher.group(1).replaceAll(" ", ""));
+            }
+
+            // unescape HTML method text
+            final String plainText = unescapeHtml(methodTextBuilder.toString());
+            final String argsString = plainText.substring(plainText.indexOf('(') + 1, plainText.indexOf(')'));
+            final Matcher argMatcher = ApiMethodParser.ARGS_PATTERN.matcher(argsString);
+            final List<String> argNames = new ArrayList<String>();
+            while (argMatcher.find()) {
+                argNames.add(argMatcher.group(3));
+            }
+
+            // make sure number of types and names match
+            if (typeList.size() != argNames.size()) {
+                throw new IllegalArgumentException("Unexpected Javadoc error, different number of arg types and names");
+            }
+
+            final String[] names = argNames.toArray(new String[argNames.size()]);
             StringBuilder builder = new StringBuilder("(");
-            for (int i = 0; i < types.length; i++) {
+            int i = 0;
+            for (String type : typeList) {
                 // split on space or non-breaking space
-                final String[] arg = args[i].trim().split(" |\u00A0");
-                builder.append(types[i]).append(" ").append(arg[1].trim()).append(",");
+                builder.append(type).append(" ").append(names[i]).append(",");
             }
             builder.deleteCharAt(builder.length() - 1);
             builder.append(")");


[2/2] git commit: Fixed APIMethodParser to support generic class parameters with multiple type arguments, e.g. Map, added tests for same

Posted by dh...@apache.org.
Fixed APIMethodParser to support generic class parameters with multiple type arguments, e.g. Map<String, String>, added tests for same


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

Branch: refs/heads/master
Commit: 909077a133eff456355aad8fc73283d62cb2060c
Parents: 7616b43
Author: Dhiraj Bokde <dh...@yahoo.com>
Authored: Fri Jun 20 13:41:35 2014 -0700
Committer: Dhiraj Bokde <dh...@yahoo.com>
Committed: Fri Jun 20 14:09:20 2014 -0700

----------------------------------------------------------------------
 .../camel/util/component/ApiMethodParser.java   | 40 ++++++++------------
 .../util/component/ApiMethodHelperTest.java     | 24 +++++++++++-
 .../ArgumentSubstitutionParserTest.java         | 20 ++++++----
 .../apache/camel/util/component/TestProxy.java  | 12 ++++++
 4 files changed, 62 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/909077a1/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 c5331be..f545202 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
@@ -35,10 +35,12 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class ApiMethodParser<T> {
 
-    private static final String METHOD_PREFIX = "^(\\s*(public|final|synchronized|native)\\s+)*(\\s*<[^\\>]>)?\\s*(\\S+)\\s+([^\\(]+\\s*)\\(";
-    private static final Pattern METHOD_PATTERN = Pattern.compile("\\s*(\\S+)\\s+(\\S+)\\s*\\(\\s*([\\S\\s,]*)\\)\\s*;?\\s*");
-    private static final Pattern ARGS_PATTERN = Pattern.compile("\\s*(\\S+)\\s+([^\\s,]+)\\s*,?");
-    private static final Pattern GENERIC_ARG_PATTERN = Pattern.compile("(\\S+)<([^>]+)>");
+    // also used by JavadocApiMethodGeneratorMojo
+    public static final Pattern ARGS_PATTERN = Pattern.compile("\\s*([^<\\s]+)\\s*(<[^>]+>)?\\s+([^\\s,]+)\\s*,?");
+
+    private static final String METHOD_PREFIX = "^(\\s*(public|final|synchronized|native)\\s+)*(\\s*<[^>]>)?\\s*(\\S+)\\s+([^\\(]+\\s*)\\(";
+    private static final Pattern METHOD_PATTERN = Pattern.compile("\\s*([^<\\s]+)\\s*(<[^>]+>)?\\s+(\\S+)\\s*\\(\\s*([\\S\\s,]*)\\)\\s*;?\\s*");
+
     private static final String JAVA_LANG = "java.lang.";
     private static final Map<String, Class> PRIMITIVE_TYPES;
 
@@ -110,32 +112,22 @@ public abstract class ApiMethodParser<T> {
                 throw new IllegalArgumentException("Invalid method signature " + signature);
             }
 
-            // drop any generic type parameters in result, if any
-            final String resultTypeWithArgs = methodMatcher.group(1);
-            final Matcher resultMatcher = GENERIC_ARG_PATTERN.matcher(resultTypeWithArgs);
-            final Class<?> resultType = (resultMatcher.matches()) ?
-                forName(resultMatcher.group(1)) : forName(resultTypeWithArgs);
-
-            final String name = methodMatcher.group(2);
-            final String argSignature = methodMatcher.group(3);
+            // ignore generic type parameters in result, if any
+            final Class<?> resultType = forName(methodMatcher.group(1));
+            final String name = methodMatcher.group(3);
+            final String argSignature = methodMatcher.group(4);
 
             final List<Argument> arguments = new ArrayList<Argument>();
+            final List<Class<?>> argTypes = new ArrayList<Class<?>>();
 
-            List<Class<?>> argTypes = new ArrayList<Class<?>>();
             final Matcher argsMatcher = ARGS_PATTERN.matcher(argSignature);
             while (argsMatcher.find()) {
-                final String argTypeWithParams = argsMatcher.group(1);
-                final Matcher genericMatcher = GENERIC_ARG_PATTERN.matcher(argTypeWithParams);
-                Class<?> type;
-                String typeArgs = null;
-                if (genericMatcher.matches()) {
-                    type = forName(genericMatcher.group(1));
-                    typeArgs = genericMatcher.group(2);
-                } else {
-                    type = forName(argTypeWithParams);
-                }
-                arguments.add(new Argument(argsMatcher.group(2), type, typeArgs));
+
+                final Class<?> type = forName(argsMatcher.group(1));
                 argTypes.add(type);
+
+                final String typeArgs = argsMatcher.group(2) != null ? argsMatcher.group(2).replaceAll(" ", "") : null;
+                arguments.add(new Argument(argsMatcher.group(3), type, typeArgs));
             }
 
             Method method;

http://git-wip-us.apache.org/repos/asf/camel/blob/909077a1/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java b/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
index 93597aa..38994d6 100644
--- a/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/component/ApiMethodHelperTest.java
@@ -22,9 +22,12 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 
-import org.junit.Test;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
 
 public class ApiMethodHelperTest {
 
@@ -53,6 +56,9 @@ public class ApiMethodHelperTest {
 
         methods = apiMethodHelper.getCandidateMethods("greetUs", "name1");
         assertEquals("Can't find greetUs(name1, name2)", 1, methods.size());
+
+        methods = apiMethodHelper.getCandidateMethods("greetAll", "nameMap");
+        assertEquals("Can't find greetAll(nameMap)", 1, methods.size());
     }
 
     @Test
@@ -81,6 +87,7 @@ public class ApiMethodHelperTest {
         assertEquals("GetArguments failed for hi", 2, apiMethodHelper.getArguments("hi").size());
         assertEquals("GetArguments failed for greetMe", 2, apiMethodHelper.getArguments("greetMe").size());
         assertEquals("GetArguments failed for greetUs", 4, apiMethodHelper.getArguments("greetUs").size());
+        assertEquals("GetArguments failed for greetAll", 6, apiMethodHelper.getArguments("greetAll").size());
     }
 
     @Test
@@ -101,7 +108,7 @@ public class ApiMethodHelperTest {
 
     @Test
     public void testAllArguments() throws Exception {
-        assertEquals("Get all arguments", 6, apiMethodHelper.allArguments().size());
+        assertEquals("Get all arguments", 7, apiMethodHelper.allArguments().size());
     }
 
     @Test
@@ -109,6 +116,7 @@ public class ApiMethodHelperTest {
         assertEquals("Get type name", String.class, apiMethodHelper.getType("name"));
         assertEquals("Get type name1", String.class, apiMethodHelper.getType("name1"));
         assertEquals("Get type name2", String.class, apiMethodHelper.getType("name2"));
+        assertEquals("Get type nameMap", Map.class, apiMethodHelper.getType("nameMap"));
     }
 
     @Test
@@ -137,6 +145,17 @@ public class ApiMethodHelperTest {
         properties.put("names", new String[] {"Dave", "Frank"});
         assertEquals("greetAll(names)", "Greetings Dave, Frank", ApiMethodHelper.invokeMethod(proxy, TestMethod.GREETALL, properties));
 
+        properties.clear();
+        Map<String, String> nameMap = new HashMap<String, String>();
+        nameMap.put("Dave", "Hello");
+        nameMap.put("Frank", "Goodbye");
+        properties.put("nameMap", nameMap);
+        final Map<String, String> result = (Map<String, String>) ApiMethodHelper.invokeMethod(proxy, TestMethod.GREETALL_2, properties);
+        assertNotNull("greetAll(nameMap)", result);
+        for (Map.Entry<String, String> entry : result.entrySet()) {
+            assertTrue("greetAll(nameMap)", entry.getValue().endsWith(entry.getKey()));
+        }
+
         // test with a derived proxy
         proxy = new TestProxy() {
             @Override
@@ -157,6 +176,7 @@ public class ApiMethodHelperTest {
         GREETUS(String.class, "greetUs", String.class, "name1", String.class, "name2"),
         GREETALL(String.class, "greetAll", new String[0].getClass(), "names"),
         GREETALL_1(String.class, "greetAll", List.class, "nameList"),
+        GREETALL_2(Map.class, "greetAll", Map.class, "nameMap"),
         GREETTIMES(new String[0].getClass(), "greetTimes", String.class, "name", int.class, "times");
 
         private final ApiMethod apiMethod;

http://git-wip-us.apache.org/repos/asf/camel/blob/909077a1/camel-core/src/test/java/org/apache/camel/util/component/ArgumentSubstitutionParserTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/component/ArgumentSubstitutionParserTest.java b/camel-core/src/test/java/org/apache/camel/util/component/ArgumentSubstitutionParserTest.java
index 6f095b4..fbd4842 100644
--- a/camel-core/src/test/java/org/apache/camel/util/component/ArgumentSubstitutionParserTest.java
+++ b/camel-core/src/test/java/org/apache/camel/util/component/ArgumentSubstitutionParserTest.java
@@ -19,9 +19,9 @@ package org.apache.camel.util.component;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.junit.Test;
-import static org.apache.camel.util.component.ArgumentSubstitutionParser.*;
+import static org.apache.camel.util.component.ArgumentSubstitutionParser.Substitution;
 import static org.junit.Assert.assertEquals;
+import org.junit.Test;
 
 public class ArgumentSubstitutionParserTest {
 
@@ -45,28 +45,32 @@ public class ArgumentSubstitutionParserTest {
         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 java.util.Map<String, String> greetAll(java.util.Map<String> nameMap);");
         signatures.add("public final String[] greetTimes(String name, int times);");
         parser.setSignatures(signatures);
 
         final List<ApiMethodParser.ApiMethodModel> methodModels = parser.parse();
-        assertEquals(7, methodModels.size());
+        assertEquals(8, methodModels.size());
 
-        final ApiMethodParser.ApiMethodModel sayHi1 = methodModels.get(6);
+        final ApiMethodParser.ApiMethodModel sayHi1 = methodModels.get(7);
         assertEquals(PERSON, sayHi1.getArguments().get(0).getName());
         assertEquals("SAYHI_1", sayHi1.getUniqueName());
 
-        final ApiMethodParser.ApiMethodModel greetMe = methodModels.get(2);
+        final ApiMethodParser.ApiMethodModel greetMe = methodModels.get(3);
         assertEquals(PERSON, greetMe.getArguments().get(0).getName());
 
-        final ApiMethodParser.ApiMethodModel greetUs = methodModels.get(4);
+        final ApiMethodParser.ApiMethodModel greetUs = methodModels.get(5);
         assertEquals("astronaut1", greetUs.getArguments().get(0).getName());
         assertEquals("astronaut2", greetUs.getArguments().get(1).getName());
 
         final ApiMethodParser.ApiMethodModel greetAll = methodModels.get(0);
-        assertEquals("personsList", greetAll.getArguments().get(0).getName());
+        assertEquals("personMap", greetAll.getArguments().get(0).getName());
 
         final ApiMethodParser.ApiMethodModel greetAll1 = methodModels.get(1);
-        assertEquals("stringArray", greetAll1.getArguments().get(0).getName());
+        assertEquals("personsList", greetAll1.getArguments().get(0).getName());
+
+        final ApiMethodParser.ApiMethodModel greetAll2 = methodModels.get(2);
+        assertEquals("stringArray", greetAll2.getArguments().get(0).getName());
     }
 
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/909077a1/camel-core/src/test/java/org/apache/camel/util/component/TestProxy.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/util/component/TestProxy.java b/camel-core/src/test/java/org/apache/camel/util/component/TestProxy.java
index d707eb8..2b4a320 100644
--- a/camel-core/src/test/java/org/apache/camel/util/component/TestProxy.java
+++ b/camel-core/src/test/java/org/apache/camel/util/component/TestProxy.java
@@ -17,7 +17,9 @@
 package org.apache.camel.util.component;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 class TestProxy {
     public String sayHi() {
@@ -61,4 +63,14 @@ class TestProxy {
         }
         return result.toArray(new String[result.size()]);
     }
+
+    public Map<String, String> greetAll(Map<String, String> nameMap) {
+        Map<String, String> result = new HashMap<String, String>();
+        for (Map.Entry<String, String> entry : nameMap.entrySet()) {
+            final String name = entry.getKey();
+            final String greeting = entry.getValue();
+            result.put(name, greeting + " " + name);
+        }
+        return result;
+    }
 }