You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2020/09/16 07:17:12 UTC

[camel] branch api updated (d0eeaaf -> 00c3d24)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a change to branch api
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from d0eeaaf  CAMEL-15478: Regen
     new d8ffccb  CAMEL-15478: API parameters that have java types in generics should be preserved.
     new e4f5744  CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.
     new 6f6c1b9  CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.
     new 00c3d24  CAMEL-15478: Generated api source now includes correct return type and handles primitive arrays better.

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../box/internal/BoxFilesManagerApiMethod.java     |   2 +-
 .../fhir/internal/FhirCapabilitiesApiMethod.java   |   2 +-
 .../fhir/internal/FhirHistoryApiMethod.java        |   6 +-
 .../fhir/internal/FhirLoadPageApiMethod.java       |   6 +-
 .../component/fhir/internal/FhirMetaApiMethod.java |  10 +-
 .../fhir/internal/FhirOperationApiMethod.java      |   2 +-
 .../twilio/MessageEndpointConfiguration.java       |   6 +-
 .../MessageEndpointConfigurationConfigurer.java    |   9 ++
 .../zendesk/internal/ZendeskApiMethod.java         |  16 +--
 .../maven/AbstractApiMethodGeneratorMojo.java      |   8 +-
 .../org/apache/camel/maven/JavaSourceParser.java   | 147 +++++++++++----------
 11 files changed, 120 insertions(+), 94 deletions(-)


[camel] 01/04: CAMEL-15478: API parameters that have java types in generics should be preserved.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch api
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d8ffccb6d563e9b74c389e65db1fb0b3b5f3f79f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Sep 16 07:03:07 2020 +0200

    CAMEL-15478: API parameters that have java types in generics should be preserved.
---
 .../camel/component/twilio/MessageEndpointConfiguration.java     | 6 +++---
 .../component/twilio/MessageEndpointConfigurationConfigurer.java | 9 +++++++++
 .../src/main/java/org/apache/camel/maven/JavaSourceParser.java   | 6 +++++-
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfiguration.java b/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfiguration.java
index f3f6913..1edb881 100644
--- a/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfiguration.java
+++ b/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfiguration.java
@@ -27,7 +27,7 @@ public final class MessageEndpointConfiguration extends TwilioConfiguration {
     private com.twilio.type.PhoneNumber from;
     @UriParam
     @ApiParam(apiMethods = {@ApiMethod(methodName = "creator", description="The URL of the media to send with the message")})
-    private java.util.List mediaUrl;
+    private java.util.List<java.net.URI> mediaUrl;
     @UriParam
     @ApiParam(apiMethods = {@ApiMethod(methodName = "creator", description="The SID of the Messaging Service you want to associate with the message")})
     private String messagingServiceSid;
@@ -57,11 +57,11 @@ public final class MessageEndpointConfiguration extends TwilioConfiguration {
         this.from = from;
     }
 
-    public java.util.List getMediaUrl() {
+    public java.util.List<java.net.URI> getMediaUrl() {
         return mediaUrl;
     }
 
-    public void setMediaUrl(java.util.List mediaUrl) {
+    public void setMediaUrl(java.util.List<java.net.URI> mediaUrl) {
         this.mediaUrl = mediaUrl;
     }
 
diff --git a/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfigurationConfigurer.java b/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfigurationConfigurer.java
index 4453075..583978a 100644
--- a/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfigurationConfigurer.java
+++ b/components/camel-twilio/src/generated/java/org/apache/camel/component/twilio/MessageEndpointConfigurationConfigurer.java
@@ -81,5 +81,14 @@ public class MessageEndpointConfigurationConfigurer extends org.apache.camel.sup
         default: return null;
         }
     }
+
+    @Override
+    public Object getCollectionValueType(Object target, String name, boolean ignoreCase) {
+        switch (ignoreCase ? name.toLowerCase() : name) {
+        case "mediaurl":
+        case "MediaUrl": return java.net.URI.class;
+        default: return null;
+        }
+    }
 }
 
diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
index 8268a56..60286b0 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
@@ -143,8 +143,12 @@ public class JavaSourceParser {
                     }
                     if (!bounds && !found) {
                         // argh this is getting complex, it may be T or just java.lang.String but this **** generics and roaster
-                        // does not make this easy, so let see if we can resolve each type variable
+                        // does not make this easy, so let see if we can find out if all the types are a qualified type or only a variable
                         boolean fqn = types.stream().allMatch(t -> {
+                            // if its from java itself then its okay
+                            if (t.getQualifiedName().startsWith("java")) {
+                                return true;
+                            }
                             // okay lets assume its a type variable if the name is upper case only
                             boolean upperOnly = isUpperCaseOnly(t.getName());
                             return !upperOnly && t.getQualifiedName().indexOf('.') != -1;


[camel] 04/04: CAMEL-15478: Generated api source now includes correct return type and handles primitive arrays better.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch api
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 00c3d249fca114bd55eecf27007f09cfe35dfb91
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Sep 16 09:16:48 2020 +0200

    CAMEL-15478: Generated api source now includes correct return type and handles primitive arrays better.
---
 .../component/box/internal/BoxFilesManagerApiMethod.java |  2 +-
 .../fhir/internal/FhirCapabilitiesApiMethod.java         |  2 +-
 .../component/fhir/internal/FhirHistoryApiMethod.java    |  6 +++---
 .../component/fhir/internal/FhirLoadPageApiMethod.java   |  6 +++---
 .../camel/component/fhir/internal/FhirMetaApiMethod.java | 10 +++++-----
 .../component/fhir/internal/FhirOperationApiMethod.java  |  2 +-
 .../component/zendesk/internal/ZendeskApiMethod.java     | 16 ++++++++--------
 .../camel/maven/AbstractApiMethodGeneratorMojo.java      |  8 ++++++--
 8 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/components/camel-box/camel-box-component/src/generated/java/org/apache/camel/component/box/internal/BoxFilesManagerApiMethod.java b/components/camel-box/camel-box-component/src/generated/java/org/apache/camel/component/box/internal/BoxFilesManagerApiMethod.java
index 06da5ce..ff985e0 100644
--- a/components/camel-box/camel-box-component/src/generated/java/org/apache/camel/component/box/internal/BoxFilesManagerApiMethod.java
+++ b/components/camel-box/camel-box-component/src/generated/java/org/apache/camel/component/box/internal/BoxFilesManagerApiMethod.java
@@ -105,7 +105,7 @@ public enum BoxFilesManagerApiMethod implements ApiMethod {
         arg("fileId", String.class)),
 
     GET_FILE_THUMBNAIL(
-        byte.class,
+        byte[].class,
         "getFileThumbnail",
         arg("fileId", String.class),
         arg("fileType", com.box.sdk.BoxFile.ThumbnailFileType.class),
diff --git a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirCapabilitiesApiMethod.java b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirCapabilitiesApiMethod.java
index 5a2509c..48a8f0b 100644
--- a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirCapabilitiesApiMethod.java
+++ b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirCapabilitiesApiMethod.java
@@ -21,7 +21,7 @@ import static org.apache.camel.support.component.ApiMethodArg.arg;
 public enum FhirCapabilitiesApiMethod implements ApiMethod {
 
     OF_TYPE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseConformance.class,
         "ofType",
         arg("type", Class.class),
         arg("extraParameters", java.util.Map.class));
diff --git a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirHistoryApiMethod.java b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirHistoryApiMethod.java
index 24d7f99..cd8f1df 100644
--- a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirHistoryApiMethod.java
+++ b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirHistoryApiMethod.java
@@ -21,7 +21,7 @@ import static org.apache.camel.support.component.ApiMethodArg.arg;
 public enum FhirHistoryApiMethod implements ApiMethod {
 
     ON_INSTANCE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "onInstance",
         arg("id", org.hl7.fhir.instance.model.api.IIdType.class),
         arg("returnType", Class.class),
@@ -31,7 +31,7 @@ public enum FhirHistoryApiMethod implements ApiMethod {
         arg("extraParameters", java.util.Map.class)),
 
     ON_SERVER(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "onServer",
         arg("returnType", Class.class),
         arg("count", Integer.class),
@@ -40,7 +40,7 @@ public enum FhirHistoryApiMethod implements ApiMethod {
         arg("extraParameters", java.util.Map.class)),
 
     ON_TYPE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "onType",
         arg("resourceType", Class.class),
         arg("returnType", Class.class),
diff --git a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirLoadPageApiMethod.java b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirLoadPageApiMethod.java
index f98f8d4..3999793 100644
--- a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirLoadPageApiMethod.java
+++ b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirLoadPageApiMethod.java
@@ -21,20 +21,20 @@ import static org.apache.camel.support.component.ApiMethodArg.arg;
 public enum FhirLoadPageApiMethod implements ApiMethod {
 
     BY_URL(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "byUrl",
         arg("url", String.class),
         arg("returnType", Class.class),
         arg("extraParameters", java.util.Map.class)),
 
     NEXT(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "next",
         arg("bundle", org.hl7.fhir.instance.model.api.IBaseBundle.class),
         arg("extraParameters", java.util.Map.class)),
 
     PREVIOUS(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "previous",
         arg("bundle", org.hl7.fhir.instance.model.api.IBaseBundle.class),
         arg("extraParameters", java.util.Map.class));
diff --git a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirMetaApiMethod.java b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirMetaApiMethod.java
index c6c5e27..03e71d6 100644
--- a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirMetaApiMethod.java
+++ b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirMetaApiMethod.java
@@ -21,34 +21,34 @@ import static org.apache.camel.support.component.ApiMethodArg.arg;
 public enum FhirMetaApiMethod implements ApiMethod {
 
     ADD(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseMetaType.class,
         "add",
         arg("meta", org.hl7.fhir.instance.model.api.IBaseMetaType.class),
         arg("id", org.hl7.fhir.instance.model.api.IIdType.class),
         arg("extraParameters", java.util.Map.class)),
 
     DELETE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseMetaType.class,
         "delete",
         arg("meta", org.hl7.fhir.instance.model.api.IBaseMetaType.class),
         arg("id", org.hl7.fhir.instance.model.api.IIdType.class),
         arg("extraParameters", java.util.Map.class)),
 
     GET_FROM_RESOURCE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseMetaType.class,
         "getFromResource",
         arg("metaType", Class.class),
         arg("id", org.hl7.fhir.instance.model.api.IIdType.class),
         arg("extraParameters", java.util.Map.class)),
 
     GET_FROM_SERVER(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseMetaType.class,
         "getFromServer",
         arg("metaType", Class.class),
         arg("extraParameters", java.util.Map.class)),
 
     GET_FROM_TYPE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseMetaType.class,
         "getFromType",
         arg("metaType", Class.class),
         arg("resourceType", String.class),
diff --git a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirOperationApiMethod.java b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirOperationApiMethod.java
index 2a5ade0..10800f2 100644
--- a/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirOperationApiMethod.java
+++ b/components/camel-fhir/camel-fhir-component/src/generated/java/org/apache/camel/component/fhir/internal/FhirOperationApiMethod.java
@@ -64,7 +64,7 @@ public enum FhirOperationApiMethod implements ApiMethod {
         arg("extraParameters", java.util.Map.class)),
 
     PROCESS_MESSAGE(
-        Object.class,
+        org.hl7.fhir.instance.model.api.IBaseBundle.class,
         "processMessage",
         arg("respondToUri", String.class),
         arg("msgBundle", org.hl7.fhir.instance.model.api.IBaseBundle.class),
diff --git a/components/camel-zendesk/src/generated/java/org/apache/camel/component/zendesk/internal/ZendeskApiMethod.java b/components/camel-zendesk/src/generated/java/org/apache/camel/component/zendesk/internal/ZendeskApiMethod.java
index 6ca9ea6..92ee35a 100644
--- a/components/camel-zendesk/src/generated/java/org/apache/camel/component/zendesk/internal/ZendeskApiMethod.java
+++ b/components/camel-zendesk/src/generated/java/org/apache/camel/component/zendesk/internal/ZendeskApiMethod.java
@@ -286,14 +286,14 @@ public enum ZendeskApiMethod implements ApiMethod {
         org.zendesk.client.v2.model.Attachment.Upload.class,
         "createUpload",
         arg("fileName", String.class),
-        arg("content", new byte[0].getClass())),
+        arg("content", byte[].class)),
 
     CREATE_UPLOAD_1(
         org.zendesk.client.v2.model.Attachment.Upload.class,
         "createUpload",
         arg("fileName", String.class),
         arg("contentType", String.class),
-        arg("content", new byte[0].getClass())),
+        arg("content", byte[].class)),
 
     CREATE_UPLOAD_2(
         org.zendesk.client.v2.model.Attachment.Upload.class,
@@ -301,7 +301,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         arg("token", String.class),
         arg("fileName", String.class),
         arg("contentType", String.class),
-        arg("content", new byte[0].getClass())),
+        arg("content", byte[].class)),
 
     CREATE_UPLOAD_ARTICLE(
         org.zendesk.client.v2.model.hc.ArticleAttachments.class,
@@ -467,7 +467,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         void.class,
         "deleteOrganizationMemberships",
         arg("id", long.class),
-        arg("ids", new long[0].getClass())),
+        arg("ids", long[].class)),
 
     DELETE_PERMISSION_GROUP(
         void.class,
@@ -523,7 +523,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         void.class,
         "deleteTickets",
         arg("id", long.class),
-        arg("ids", new long[0].getClass())),
+        arg("ids", long[].class)),
 
     DELETE_TOPIC(
         void.class,
@@ -1196,7 +1196,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         java.util.List.class,
         "getTickets",
         arg("id", long.class),
-        arg("ids", new long[0].getClass())),
+        arg("ids", long[].class)),
 
     GET_TICKETS_BY_EXTERNAL_ID(
         Iterable.class,
@@ -1248,7 +1248,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         java.util.List.class,
         "getTopics",
         arg("id", long.class),
-        arg("ids", new long[0].getClass())),
+        arg("ids", long[].class)),
 
     GET_TOPICS_BY_USER(
         java.util.List.class,
@@ -1462,7 +1462,7 @@ public enum ZendeskApiMethod implements ApiMethod {
         org.zendesk.client.v2.model.JobStatus.class,
         "permanentlyDeleteTickets",
         arg("id", long.class),
-        arg("ids", new long[0].getClass())),
+        arg("ids", long[].class)),
 
     PERMANENTLY_DELETE_USER(
         org.zendesk.client.v2.model.User.class,
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 51db0d0..704994f 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
@@ -291,8 +291,12 @@ public abstract class AbstractApiMethodGeneratorMojo extends AbstractApiMethodBa
 
     public static String getType(Class<?> clazz) {
         if (clazz.isArray()) {
-            // create a zero length array and get the class from the instance
-            return "new " + getCanonicalName(clazz).replaceAll("\\[\\]", "[0]") + ".getClass()";
+            if (clazz.getComponentType().isPrimitive()) {
+                return getCanonicalName(clazz) + ".class";
+            } else {
+                // create a zero length array and get the class from the instance
+                return "new " + getCanonicalName(clazz).replaceAll("\\[\\]", "[0]") + ".getClass()";
+            }
         } else {
             return getCanonicalName(clazz) + ".class";
         }


[camel] 02/04: CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch api
in repository https://gitbox.apache.org/repos/asf/camel.git

commit e4f5744ec65a9a5c9d36faa82f0292899148d278
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Sep 16 09:00:19 2020 +0200

    CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.
---
 .../org/apache/camel/maven/JavaSourceParser.java   | 88 ++++++++++++++++++----
 1 file changed, 75 insertions(+), 13 deletions(-)

diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
index 60286b0..a05596e 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
@@ -37,6 +37,8 @@ import org.jboss.forge.roaster.model.source.MethodHolderSource;
 import org.jboss.forge.roaster.model.source.MethodSource;
 import org.jboss.forge.roaster.model.source.ParameterSource;
 import org.jboss.forge.roaster.model.source.TypeVariableSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static org.apache.camel.tooling.util.JavadocHelper.sanitizeDescription;
 
@@ -45,6 +47,8 @@ import static org.apache.camel.tooling.util.JavadocHelper.sanitizeDescription;
  */
 public class JavaSourceParser {
 
+    private static final Logger LOG = LoggerFactory.getLogger(JavaSourceParser.class);
+
     private List<String> methods = new ArrayList<>();
     private Map<String, String> methodText = new HashMap<>();
     private Map<String, Map<String, String>> parameters = new LinkedHashMap<>();
@@ -53,6 +57,65 @@ public class JavaSourceParser {
     private String apiDescription;
     private final Map<String, String> methodDescriptions = new HashMap<>();
 
+    private static String resolveParameterizedType(
+            AbstractGenericCapableJavaSource clazz, MethodSource ms, ParameterSource ps, Type type) {
+        String answer = resolveType(clazz, clazz, ms, type);
+
+        if (type.isParameterized()) {
+            // for parameterized types then it can get complex if they are variables (T, T extends Foo etc)
+            // or if there are no bounds for these types which we then can't resolve.
+            List<Type> types = type.getTypeArguments();
+            boolean bounds = false;
+            boolean found = false;
+            for (Type t : types) {
+                if (hasTypeVariableBounds(ms, clazz, t.getName())) {
+                    bounds = true;
+                    // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
+                    // what base class that is
+                    String tn = resolveTypeVariable(ms, clazz, t.getName());
+                    if (tn != null) {
+                        answer = answer.replace(t.getName(), tn);
+                        found = true;
+                    }
+                }
+            }
+            if (!bounds && !found) {
+                // argh this is getting complex, it may be T or just java.lang.String but this **** generics and roaster
+                // does not make this easy, so let see if we can find out if all the types are a qualified type or only a variable
+                boolean fqn = types.stream().allMatch(t -> {
+                    // if its from java itself then its okay
+                    if (t.getQualifiedName().startsWith("java")) {
+                        return true;
+                    }
+                    // okay lets assume its a type variable if the name is upper case only
+                    boolean upperOnly = isUpperCaseOnly(t.getName());
+                    return !upperOnly && t.getQualifiedName().indexOf('.') != -1;
+                });
+                if (!fqn) {
+                    // remove generics we could not resolve that even if we have bounds information
+                    bounds = true;
+                    found = false;
+                }
+            }
+            if (bounds && !found) {
+                // remove generics we could not resolve that even if we have bounds information
+                answer = type.getQualifiedName();
+            }
+        } else if (ms.hasTypeVariable(answer) || clazz.hasTypeVariable(answer)) {
+            // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
+            // what base class that is
+            answer = resolveTypeVariable(ms, clazz, answer);
+        }
+        if ((ps != null && ps.isVarArgs()) || type.isArray()) {
+            // the old way with javadoc did not use varargs in the signature, so lets transform this to an array style
+            answer = answer + "[]";
+        }
+
+        // remove java.lang. prefix as it should not be there
+        answer = answer.replaceAll("java.lang.", "");
+        return answer;
+    }
+
     @SuppressWarnings("unchecked")
     public synchronized void parse(InputStream in, String innerClass) throws Exception {
         AbstractGenericCapableJavaSource rootClazz = (AbstractGenericCapableJavaSource) Roaster.parse(in);
@@ -67,6 +130,8 @@ public class JavaSourceParser {
             }
         }
 
+        LOG.debug("Parsing class: {}", clazz.getQualifiedName());
+
         String rawClass = clazz.toUnformattedString();
         String doc = getClassJavadocRaw(clazz, rawClass);
         apiDescription = sanitizeJavaDocValue(doc, true);
@@ -81,6 +146,9 @@ public class JavaSourceParser {
 
         List<MethodSource> ml = ((MethodHolderSource) clazz).getMethods();
         for (MethodSource ms : ml) {
+            String methodName = ms.getName();
+            LOG.debug("Parsing method: {}", methodName);
+
             // should not be constructor and must not be private
             boolean isInterface = clazz instanceof JavaInterfaceSource;
             boolean accept = isInterface || (!ms.isConstructor() && ms.isPublic());
@@ -97,20 +165,11 @@ public class JavaSourceParser {
                 methodDescriptions.put(ms.getName(), doc);
             }
 
-            String result;
-            Type rt = ms.getReturnType();
-            boolean hasTypeVariables = ms.hasTypeVariable(rt.getName()) || clazz.hasTypeVariable(rt.getName());
-            if (hasTypeVariables) {
-                // okay this gets to complex then remove the generics
-                result = "Object";
-            } else {
-                result = resolveType(rootClazz, clazz, ms, rt);
-                if (result == null || result.isEmpty()) {
-                    result = "void";
-                }
+            String result = resolveParameterizedType(clazz, ms, null, ms.getReturnType());
+            if (result.isEmpty()) {
+                result = "void";
             }
-            // remove java.lang. prefix as it should not be there
-            result = result.replaceAll("java.lang.", "");
+            LOG.trace("Parsed return type as: {}", result);
 
             List<JavaDocTag> params = ms.getJavaDoc().getTags("@param");
 
@@ -123,6 +182,9 @@ public class JavaSourceParser {
                 ParameterSource ps = list.get(i);
                 String name = ps.getName();
                 String type = resolveType(rootClazz, clazz, ms, ps.getType());
+                LOG.trace("Parsing parameter #{} ({} {})", i, type, name);
+
+                // TODO: Call that other method
                 if (ps.getType().isParameterized()) {
                     // for parameterized types then it can get complex if they are variables (T, T extends Foo etc)
                     // or if there are no bounds for these types which we then can't resolve.


[camel] 03/04: CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch api
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 6f6c1b98802e0cc21a73820696bec59c0de52076
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Sep 16 09:03:28 2020 +0200

    CAMEL-15478: Java source parser should resolve return type that may be generic and parameterized.
---
 .../org/apache/camel/maven/JavaSourceParser.java   | 187 ++++++++-------------
 1 file changed, 67 insertions(+), 120 deletions(-)

diff --git a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
index a05596e..dbc3fa0 100644
--- a/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
+++ b/tooling/maven/camel-api-component-maven-plugin/src/main/java/org/apache/camel/maven/JavaSourceParser.java
@@ -57,65 +57,6 @@ public class JavaSourceParser {
     private String apiDescription;
     private final Map<String, String> methodDescriptions = new HashMap<>();
 
-    private static String resolveParameterizedType(
-            AbstractGenericCapableJavaSource clazz, MethodSource ms, ParameterSource ps, Type type) {
-        String answer = resolveType(clazz, clazz, ms, type);
-
-        if (type.isParameterized()) {
-            // for parameterized types then it can get complex if they are variables (T, T extends Foo etc)
-            // or if there are no bounds for these types which we then can't resolve.
-            List<Type> types = type.getTypeArguments();
-            boolean bounds = false;
-            boolean found = false;
-            for (Type t : types) {
-                if (hasTypeVariableBounds(ms, clazz, t.getName())) {
-                    bounds = true;
-                    // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
-                    // what base class that is
-                    String tn = resolveTypeVariable(ms, clazz, t.getName());
-                    if (tn != null) {
-                        answer = answer.replace(t.getName(), tn);
-                        found = true;
-                    }
-                }
-            }
-            if (!bounds && !found) {
-                // argh this is getting complex, it may be T or just java.lang.String but this **** generics and roaster
-                // does not make this easy, so let see if we can find out if all the types are a qualified type or only a variable
-                boolean fqn = types.stream().allMatch(t -> {
-                    // if its from java itself then its okay
-                    if (t.getQualifiedName().startsWith("java")) {
-                        return true;
-                    }
-                    // okay lets assume its a type variable if the name is upper case only
-                    boolean upperOnly = isUpperCaseOnly(t.getName());
-                    return !upperOnly && t.getQualifiedName().indexOf('.') != -1;
-                });
-                if (!fqn) {
-                    // remove generics we could not resolve that even if we have bounds information
-                    bounds = true;
-                    found = false;
-                }
-            }
-            if (bounds && !found) {
-                // remove generics we could not resolve that even if we have bounds information
-                answer = type.getQualifiedName();
-            }
-        } else if (ms.hasTypeVariable(answer) || clazz.hasTypeVariable(answer)) {
-            // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
-            // what base class that is
-            answer = resolveTypeVariable(ms, clazz, answer);
-        }
-        if ((ps != null && ps.isVarArgs()) || type.isArray()) {
-            // the old way with javadoc did not use varargs in the signature, so lets transform this to an array style
-            answer = answer + "[]";
-        }
-
-        // remove java.lang. prefix as it should not be there
-        answer = answer.replaceAll("java.lang.", "");
-        return answer;
-    }
-
     @SuppressWarnings("unchecked")
     public synchronized void parse(InputStream in, String innerClass) throws Exception {
         AbstractGenericCapableJavaSource rootClazz = (AbstractGenericCapableJavaSource) Roaster.parse(in);
@@ -165,7 +106,7 @@ public class JavaSourceParser {
                 methodDescriptions.put(ms.getName(), doc);
             }
 
-            String result = resolveParameterizedType(clazz, ms, null, ms.getReturnType());
+            String result = resolveParameterizedType(rootClazz, clazz, ms, null, ms.getReturnType());
             if (result.isEmpty()) {
                 result = "void";
             }
@@ -181,63 +122,9 @@ public class JavaSourceParser {
             for (int i = 0; i < list.size(); i++) {
                 ParameterSource ps = list.get(i);
                 String name = ps.getName();
-                String type = resolveType(rootClazz, clazz, ms, ps.getType());
+                String type = resolveParameterizedType(rootClazz, clazz, ms, ps, ps.getType());
                 LOG.trace("Parsing parameter #{} ({} {})", i, type, name);
 
-                // TODO: Call that other method
-                if (ps.getType().isParameterized()) {
-                    // for parameterized types then it can get complex if they are variables (T, T extends Foo etc)
-                    // or if there are no bounds for these types which we then can't resolve.
-                    List<Type> types = ps.getType().getTypeArguments();
-                    boolean bounds = false;
-                    boolean found = false;
-                    for (Type t : types) {
-                        if (hasTypeVariableBounds(ms, clazz, t.getName())) {
-                            bounds = true;
-                            // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
-                            // what base class that is
-                            String tn = resolveTypeVariable(ms, clazz, t.getName());
-                            if (tn != null) {
-                                type = type.replace(t.getName(), tn);
-                                found = true;
-                            }
-                        }
-                    }
-                    if (!bounds && !found) {
-                        // argh this is getting complex, it may be T or just java.lang.String but this **** generics and roaster
-                        // does not make this easy, so let see if we can find out if all the types are a qualified type or only a variable
-                        boolean fqn = types.stream().allMatch(t -> {
-                            // if its from java itself then its okay
-                            if (t.getQualifiedName().startsWith("java")) {
-                                return true;
-                            }
-                            // okay lets assume its a type variable if the name is upper case only
-                            boolean upperOnly = isUpperCaseOnly(t.getName());
-                            return !upperOnly && t.getQualifiedName().indexOf('.') != -1;
-                        });
-                        if (!fqn) {
-                            // remove generics we could not resolve that even if we have bounds information
-                            bounds = true;
-                            found = false;
-                        }
-                    }
-                    if (bounds && !found) {
-                        // remove generics we could not resolve that even if we have bounds information
-                        type = ps.getType().getQualifiedName();
-                    }
-                } else if (ms.hasTypeVariable(type) || clazz.hasTypeVariable(type)) {
-                    // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
-                    // what base class that is
-                    type = resolveTypeVariable(ms, clazz, type);
-                }
-                if (ps.isVarArgs() || ps.getType().isArray()) {
-                    // the old way with javadoc did not use varargs in the signature, so lets transform this to an array style
-                    type = type + "[]";
-                }
-
-                // remove all java.lang. prefixes
-                type = type.replaceAll("java.lang.", "");
-
                 sb.append(type);
                 sb.append(" ").append(name);
                 if (i < list.size() - 1) {
@@ -264,13 +151,64 @@ public class JavaSourceParser {
         }
     }
 
-    private static boolean isUpperCaseOnly(String name) {
-        for (int i = 0; i < name.length(); i++) {
-            if (!Character.isUpperCase(name.charAt(i))) {
-                return false;
+    private static String resolveParameterizedType(
+            AbstractGenericCapableJavaSource rootClazz, AbstractGenericCapableJavaSource clazz, MethodSource ms,
+            ParameterSource ps, Type type) {
+        String answer = resolveType(rootClazz, clazz, ms, type);
+
+        if (type.isParameterized()) {
+            // for parameterized types then it can get complex if they are variables (T, T extends Foo etc)
+            // or if there are no bounds for these types which we then can't resolve.
+            List<Type> types = type.getTypeArguments();
+            boolean bounds = false;
+            boolean found = false;
+            for (Type t : types) {
+                if (hasTypeVariableBounds(ms, clazz, t.getName())) {
+                    bounds = true;
+                    // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
+                    // what base class that is
+                    String tn = resolveTypeVariable(ms, clazz, t.getName());
+                    if (tn != null) {
+                        answer = answer.replace(t.getName(), tn);
+                        found = true;
+                    }
+                }
+            }
+            if (!bounds && !found) {
+                // argh this is getting complex, it may be T or just java.lang.String but this **** generics and roaster
+                // does not make this easy, so let see if we can find out if all the types are a qualified type or only a variable
+                boolean fqn = types.stream().allMatch(t -> {
+                    // if its from java itself then its okay
+                    if (t.getQualifiedName().startsWith("java")) {
+                        return true;
+                    }
+                    // okay lets assume its a type variable if the name is upper case only
+                    boolean upperOnly = isUpperCaseOnly(t.getName());
+                    return !upperOnly && t.getQualifiedName().indexOf('.') != -1;
+                });
+                if (!fqn) {
+                    // remove generics we could not resolve that even if we have bounds information
+                    bounds = true;
+                    found = false;
+                }
             }
+            if (bounds && !found) {
+                // remove generics we could not resolve that even if we have bounds information
+                answer = type.getQualifiedName();
+            }
+        } else if (ms.hasTypeVariable(answer) || clazz.hasTypeVariable(answer)) {
+            // okay now it gets complex as we have a type like T which is a type variable and we need to resolve that into
+            // what base class that is
+            answer = resolveTypeVariable(ms, clazz, answer);
         }
-        return true;
+        if ((ps != null && ps.isVarArgs()) || type.isArray()) {
+            // the old way with javadoc did not use varargs in the signature, so lets transform this to an array style
+            answer = answer + "[]";
+        }
+
+        // remove java.lang. prefix as it should not be there
+        answer = answer.replaceAll("java.lang.", "");
+        return answer;
     }
 
     private static boolean hasTypeVariableBounds(MethodSource ms, AbstractGenericCapableJavaSource clazz, String type) {
@@ -483,6 +421,15 @@ public class JavaSourceParser {
         return desc;
     }
 
+    private static boolean isUpperCaseOnly(String name) {
+        for (int i = 0; i < name.length(); i++) {
+            if (!Character.isUpperCase(name.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     public void reset() {
         methods.clear();
         methodText.clear();