You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2022/04/14 16:51:57 UTC

[camel] branch main updated (549f94a65d0 -> 079a19a55d1)

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

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


    from 549f94a65d0 CAMEL-17969: camel-main - Property-placeholder summary
     new 2f22c70e605 CAMEL-17894: cache known Java classes
     new a00e7492728 CAMEL-17894: avoid logging and formatting strings in plugin hot path
     new 23e00cf1524 CAMEL-17894: reduce method size to simplify performance analysis
     new 079a19a55d1 CAMEL-17984: enable class caching for all other classes

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:
 .../maven/packaging/AbstractGeneratorMojo.java     |  34 ++
 .../packaging/EndpointSchemaGeneratorMojo.java     | 655 +++++++++++----------
 2 files changed, 384 insertions(+), 305 deletions(-)


[camel] 03/04: CAMEL-17894: reduce method size to simplify performance analysis

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

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

commit 23e00cf1524c55b305ab56bc601c00e7dd74d0ba
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Thu Apr 14 13:26:03 2022 +0200

    CAMEL-17894: reduce method size to simplify performance analysis
---
 .../packaging/EndpointSchemaGeneratorMojo.java     | 557 +++++++++++----------
 1 file changed, 287 insertions(+), 270 deletions(-)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
index b2cad0e7c50..72eb4265594 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
@@ -1170,15 +1170,10 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
                 }
             }
 
-            String excludedProperties = getExcludedEnd(classElement.getAnnotation(Metadata.class));
-            Metadata metadata;
-
-            final UriEndpoint uriEndpoint = classElement.getAnnotation(UriEndpoint.class);
-            if (uriEndpoint != null) {
-                Collections.addAll(excludes, excludedProperties.split(","));
-            }
-            for (Field fieldElement : classElement.getDeclaredFields()) {
+            collectExcludes(classElement, excludes);
 
+            Metadata metadata;
+            for (final Field fieldElement : classElement.getDeclaredFields()) {
                 metadata = fieldElement.getAnnotation(Metadata.class);
                 if (metadata != null && metadata.skip()) {
                     continue;
@@ -1190,125 +1185,15 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
                 }
                 Boolean secret = metadata != null ? metadata.secret() : null;
 
-                UriPath path = fieldElement.getAnnotation(UriPath.class);
-                String fieldName = fieldElement.getName();
-                // component options should not include @UriPath as they are for endpoints only
-                if (!componentOption && path != null) {
-                    String name = prefix + (Strings.isNullOrEmpty(path.name()) ? fieldName : path.name());
-
-                    // should we exclude the name?
-                    if (excludes.contains(name)) {
-                        continue;
-                    }
-
-                    Object defaultValue = path.defaultValue();
-                    if ("".equals(defaultValue) && metadata != null) {
-                        defaultValue = metadata.defaultValue();
-                    }
-                    String defaultValueNote = path.defaultValueNote();
-                    boolean required = metadata != null && metadata.required();
-                    String label = path.label();
-                    if (Strings.isNullOrEmpty(label) && metadata != null) {
-                        label = metadata.label();
-                    }
-                    String displayName = path.displayName();
-                    if (Strings.isNullOrEmpty(displayName)) {
-                        displayName = metadata != null ? metadata.displayName() : null;
-                    }
-                    // compute a display name if we don't have anything
-                    if (Strings.isNullOrEmpty(displayName)) {
-                        displayName = Strings.asTitle(name);
-                    }
-
-                    Class<?> fieldTypeElement = fieldElement.getType();
-                    String fieldTypeName = getTypeName(GenericsUtil.resolveType(orgClassElement, fieldElement));
-
-                    String docComment = path.description();
-                    if (Strings.isNullOrEmpty(docComment)) {
-                        docComment = findJavaDoc(fieldElement, fieldName, name, classElement, false);
-                    }
-
-                    // gather enums
-                    List<String> enums = gatherEnums(path, fieldTypeElement);
-
-                    // the field type may be overloaded by another type
-                    boolean isDuration = false;
-                    if (!Strings.isNullOrEmpty(path.javaType())) {
-                        String mjt = path.javaType();
-                        if ("java.time.Duration".equals(mjt)) {
-                            isDuration = true;
-                        } else {
-                            fieldTypeName = mjt;
-                        }
-                    }
-
-                    // prepare default value so its value is correct according to its type
-                    defaultValue = getDefaultValue(defaultValue, fieldTypeName, isDuration);
-
-                    boolean isSecret = secret != null && secret || path.secret();
-                    boolean isAutowired = metadata != null && metadata.autowired();
-                    String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(),
-                            componentModel.isProducerOnly());
-
-                    // generics for collection types
-                    String nestedType = null;
-                    String desc = fieldTypeName;
-                    if (desc.contains("<") && desc.contains(">")) {
-                        desc = Strings.between(desc, "<", ">");
-                        // if it has additional nested types, then we only want the outer type
-                        int pos = desc.indexOf('<');
-                        if (pos != -1) {
-                            desc = desc.substring(0, pos);
-                        }
-                        // if its a map then it has a key/value, so we only want the last part
-                        pos = desc.indexOf(',');
-                        if (pos != -1) {
-                            desc = desc.substring(pos + 1);
-                        }
-                        desc = desc.replace('$', '.');
-                        desc = desc.trim();
-                        // skip if the type is generic or a wildcard
-                        if (!desc.isEmpty() && desc.indexOf('?') == -1 && !desc.contains(" extends ")) {
-                            nestedType = desc;
-                        }
-                    }
-
-                    BaseOptionModel option;
-                    if (componentOption) {
-                        option = new ComponentOptionModel();
-                    } else {
-                        option = new EndpointOptionModel();
-                    }
-                    option.setName(name);
-                    option.setKind("path");
-                    option.setDisplayName(displayName);
-                    option.setType(getType(fieldTypeName, false, isDuration));
-                    option.setJavaType(fieldTypeName);
-                    option.setRequired(required);
-                    option.setDefaultValue(defaultValue);
-                    option.setDefaultValueNote(defaultValueNote);
-                    option.setDescription(docComment.trim());
-                    option.setDeprecated(deprecated);
-                    option.setDeprecationNote(deprecationNote);
-                    option.setSecret(isSecret);
-                    option.setAutowired(isAutowired);
-                    option.setGroup(group);
-                    option.setLabel(label);
-                    option.setEnums(enums);
-                    option.setNestedType(nestedType);
-                    option.setConfigurationClass(nestedTypeName);
-                    option.setConfigurationField(nestedFieldName);
-                    if (componentModel.getEndpointOptions().stream().noneMatch(opt -> name.equals(opt.getName()))) {
-                        componentModel.addEndpointOption((EndpointOptionModel) option);
-                    }
+                if (collectUriPathProperties(componentModel, classElement, excludes, prefix, nestedTypeName, nestedFieldName, componentOption, orgClassElement, metadata, fieldElement, deprecated, deprecationNote, secret)) {
+                    continue;
                 }
+                String fieldName;
 
                 UriParam param = fieldElement.getAnnotation(UriParam.class);
                 if (param != null) {
-                    ApiParam apiParam = fieldElement.getAnnotation(ApiParam.class);
                     fieldName = fieldElement.getName();
                     String name = prefix + (Strings.isNullOrEmpty(param.name()) ? fieldName : param.name());
-
                     // should we exclude the name?
                     if (excludes.contains(name)) {
                         continue;
@@ -1354,156 +1239,9 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
                         nestedTypeName = null;
                         nestedFieldName = null;
                     } else {
-                        String docComment = param.description();
-                        if (Strings.isNullOrEmpty(docComment)) {
-                            docComment = findJavaDoc(fieldElement, fieldName, name, classElement, false);
-                        }
-                        if (Strings.isNullOrEmpty(docComment)) {
-                            docComment = "";
-                        }
-
-                        // gather enums
-                        List<String> enums = gatherEnums(param, fieldTypeElement);
-
-                        // the field type may be overloaded by another type
-                        boolean isDuration = false;
-                        if (!Strings.isNullOrEmpty(param.javaType())) {
-                            String jt = param.javaType();
-                            if ("java.time.Duration".equals(jt)) {
-                                isDuration = true;
-                            } else {
-                                fieldTypeName = param.javaType();
-                            }
-                        }
+                        ApiParam apiParam = fieldElement.getAnnotation(ApiParam.class);
 
-                        // prepare default value so its value is correct according to its type
-                        defaultValue = getDefaultValue(defaultValue, fieldTypeName, isDuration);
-
-                        boolean isSecret = secret != null && secret || param.secret();
-                        boolean isAutowired = metadata != null && metadata.autowired();
-                        String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(),
-                                componentModel.isProducerOnly());
-
-                        // generics for collection types
-                        String nestedType = null;
-                        String desc = fieldTypeName;
-                        if (desc.contains("<") && desc.contains(">")) {
-                            desc = Strings.between(desc, "<", ">");
-                            // if it has additional nested types, then we only want the outer type
-                            int pos = desc.indexOf('<');
-                            if (pos != -1) {
-                                desc = desc.substring(0, pos);
-                            }
-                            // if its a map then it has a key/value, so we only want the last part
-                            pos = desc.indexOf(',');
-                            if (pos != -1) {
-                                desc = desc.substring(pos + 1);
-                            }
-                            desc = desc.replace('$', '.');
-                            desc = desc.trim();
-                            // skip if the type is generic or a wildcard
-                            if (!desc.isEmpty() && desc.indexOf('?') == -1 && !desc.contains(" extends ")) {
-                                nestedType = desc;
-                            }
-                        }
-
-                        BaseOptionModel option;
-                        if (componentOption) {
-                            option = new ComponentOptionModel();
-                        } else if (apiOption) {
-                            option = new ApiOptionModel();
-                        } else {
-                            option = new EndpointOptionModel();
-                        }
-                        option.setName(name);
-                        option.setDisplayName(displayName);
-                        option.setType(getType(fieldTypeName, false, isDuration));
-                        option.setJavaType(fieldTypeName);
-                        option.setRequired(required);
-                        option.setDefaultValue(defaultValue);
-                        option.setDefaultValueNote(defaultValueNote);
-                        option.setDescription(docComment.trim());
-                        option.setDeprecated(deprecated);
-                        option.setDeprecationNote(deprecationNote);
-                        option.setSecret(isSecret);
-                        option.setAutowired(isAutowired);
-                        option.setGroup(group);
-                        option.setLabel(label);
-                        option.setEnums(enums);
-                        option.setNestedType(nestedType);
-                        option.setConfigurationClass(nestedTypeName);
-                        option.setConfigurationField(nestedFieldName);
-                        option.setPrefix(paramPrefix);
-                        option.setOptionalPrefix(paramOptionalPrefix);
-                        option.setMultiValue(multiValue);
-                        if (componentOption) {
-                            option.setKind("property");
-                            componentModel.addComponentOption((ComponentOptionModel) option);
-                        } else if (apiOption && apiParam != null) {
-                            option.setKind("parameter");
-                            final String targetApiName = apiName;
-                            ApiModel api;
-                            Optional<ApiModel> op = componentModel.getApiOptions().stream()
-                                    .filter(o -> o.getName().equals(targetApiName))
-                                    .findFirst();
-                            if (!op.isPresent()) {
-                                api = new ApiModel();
-                                api.setName(apiName);
-                                componentModel.getApiOptions().add(api);
-                                if (apiParams != null) {
-                                    for (String alias : apiParams.aliases()) {
-                                        api.addAlias(alias);
-                                    }
-                                }
-                                if (apiParams != null) {
-                                    api.setDescription(apiParams.description());
-                                    // component model takes precedence
-                                    api.setConsumerOnly(componentModel.isConsumerOnly() || apiParams.consumerOnly());
-                                    api.setProducerOnly(componentModel.isProducerOnly() || apiParams.producerOnly());
-                                }
-                            } else {
-                                api = op.get();
-                            }
-                            for (ApiMethod method : apiParam.apiMethods()) {
-                                ApiMethodModel apiMethod = null;
-                                for (ApiMethodModel m : api.getMethods()) {
-                                    if (m.getName().equals(method.methodName())) {
-                                        apiMethod = m;
-                                        break;
-                                    }
-                                }
-                                if (apiMethod == null) {
-                                    apiMethod = api.newMethod(method.methodName());
-                                }
-                                // the method description is stored on @ApiParams
-                                if (apiParams != null) {
-                                    for (ApiMethod m : apiParams.apiMethods()) {
-                                        if (m.methodName().equals(method.methodName())) {
-                                            apiMethod.setDescription(m.description());
-                                            for (String sig : m.signatures()) {
-                                                apiMethod.addSignature(sig);
-                                            }
-                                            break;
-                                        }
-                                    }
-                                }
-                                // copy the option and override with the correct description
-                                ApiOptionModel copy = ((ApiOptionModel) option).copy();
-                                apiMethod.addApiOptionModel(copy);
-                                // the option description is stored on @ApiMethod
-                                copy.setDescription(method.description());
-                                // whether we are consumer or producer only
-                                group = EndpointHelper.labelAsGroupName(copy.getLabel(), api.isConsumerOnly(),
-                                        api.isProducerOnly());
-                                copy.setGroup(group);
-                                copy.setOptional(apiParam.optional());
-                            }
-                        } else {
-                            option.setKind("parameter");
-                            if (componentModel.getEndpointOptions().stream().noneMatch(opt -> name.equals(opt.getName()))) {
-                                componentModel.addEndpointOption((EndpointOptionModel) option);
-                            }
-                        }
+                        collectNonNestedField(componentModel, classElement, nestedTypeName, nestedFieldName, componentOption, apiName, apiOption, apiParams, metadata, fieldElement, deprecated, deprecationNote, secret, fieldName, param, apiParam, name, paramOptionalPrefix, paramPrefix, multiValue, defaultValue, defaultValueNote, required, label, displayName, fieldTypeElement, fieldTypeName);
                     }
                 }
             }
@@ -1524,6 +1262,284 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         }
     }
 
+    private void collectNonNestedField(ComponentModel componentModel, Class<?> classElement, String nestedTypeName, String nestedFieldName, boolean componentOption, String apiName, boolean apiOption, ApiParams apiParams, Metadata metadata, Field fieldElement, boolean deprecated, String deprecationNote, Boolean secret, String fieldName, UriParam param, ApiParam apiParam, String name, String paramOptionalPrefix, String paramPrefix, boolean multiValue, Object defaultValue, String defaultVal [...]
+        String docComment = param.description();
+        if (Strings.isNullOrEmpty(docComment)) {
+            docComment = findJavaDoc(fieldElement, fieldName, name, classElement, false);
+        }
+        if (Strings.isNullOrEmpty(docComment)) {
+            docComment = "";
+        }
+
+        // gather enums
+        List<String> enums = gatherEnums(param, fieldTypeElement);
+
+        // the field type may be overloaded by another type
+        boolean isDuration = false;
+        if (!Strings.isNullOrEmpty(param.javaType())) {
+            String jt = param.javaType();
+            if ("java.time.Duration".equals(jt)) {
+                isDuration = true;
+            } else {
+                fieldTypeName = param.javaType();
+            }
+        }
+
+        // prepare default value so its value is correct according to its type
+        defaultValue = getDefaultValue(defaultValue, fieldTypeName, isDuration);
+
+        boolean isSecret = secret != null && secret || param.secret();
+        boolean isAutowired = metadata != null && metadata.autowired();
+        String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(),
+                componentModel.isProducerOnly());
+
+        // generics for collection types
+        String nestedType = null;
+        String desc = fieldTypeName;
+        if (desc.contains("<") && desc.contains(">")) {
+            desc = Strings.between(desc, "<", ">");
+            // if it has additional nested types, then we only want the outer type
+            int pos = desc.indexOf('<');
+            if (pos != -1) {
+                desc = desc.substring(0, pos);
+            }
+            // if its a map then it has a key/value, so we only want the last part
+            pos = desc.indexOf(',');
+            if (pos != -1) {
+                desc = desc.substring(pos + 1);
+            }
+            desc = desc.replace('$', '.');
+            desc = desc.trim();
+            // skip if the type is generic or a wildcard
+            if (!desc.isEmpty() && desc.indexOf('?') == -1 && !desc.contains(" extends ")) {
+                nestedType = desc;
+            }
+        }
+
+        BaseOptionModel option;
+        if (componentOption) {
+            option = new ComponentOptionModel();
+        } else if (apiOption) {
+            option = new ApiOptionModel();
+        } else {
+            option = new EndpointOptionModel();
+        }
+        option.setName(name);
+        option.setDisplayName(displayName);
+        option.setType(getType(fieldTypeName, false, isDuration));
+        option.setJavaType(fieldTypeName);
+        option.setRequired(required);
+        option.setDefaultValue(defaultValue);
+        option.setDefaultValueNote(defaultValueNote);
+        option.setDescription(docComment.trim());
+        option.setDeprecated(deprecated);
+        option.setDeprecationNote(deprecationNote);
+        option.setSecret(isSecret);
+        option.setAutowired(isAutowired);
+        option.setGroup(group);
+        option.setLabel(label);
+        option.setEnums(enums);
+        option.setNestedType(nestedType);
+        option.setConfigurationClass(nestedTypeName);
+        option.setConfigurationField(nestedFieldName);
+        option.setPrefix(paramPrefix);
+        option.setOptionalPrefix(paramOptionalPrefix);
+        option.setMultiValue(multiValue);
+        if (componentOption) {
+            option.setKind("property");
+            componentModel.addComponentOption((ComponentOptionModel) option);
+        } else if (apiOption && apiParam != null) {
+            option.setKind("parameter");
+            final String targetApiName = apiName;
+            ApiModel api;
+            Optional<ApiModel> op = componentModel.getApiOptions().stream()
+                    .filter(o -> o.getName().equals(targetApiName))
+                    .findFirst();
+            if (!op.isPresent()) {
+                api = new ApiModel();
+                api.setName(apiName);
+                componentModel.getApiOptions().add(api);
+                if (apiParams != null) {
+                    for (String alias : apiParams.aliases()) {
+                        api.addAlias(alias);
+                    }
+                }
+                if (apiParams != null) {
+                    api.setDescription(apiParams.description());
+                    // component model takes precedence
+                    api.setConsumerOnly(componentModel.isConsumerOnly() || apiParams.consumerOnly());
+                    api.setProducerOnly(componentModel.isProducerOnly() || apiParams.producerOnly());
+                }
+            } else {
+                api = op.get();
+            }
+            for (ApiMethod method : apiParam.apiMethods()) {
+                ApiMethodModel apiMethod = null;
+                for (ApiMethodModel m : api.getMethods()) {
+                    if (m.getName().equals(method.methodName())) {
+                        apiMethod = m;
+                        break;
+                    }
+                }
+                if (apiMethod == null) {
+                    apiMethod = api.newMethod(method.methodName());
+                }
+                // the method description is stored on @ApiParams
+                if (apiParams != null) {
+                    for (ApiMethod m : apiParams.apiMethods()) {
+                        if (m.methodName().equals(method.methodName())) {
+                            apiMethod.setDescription(m.description());
+                            for (String sig : m.signatures()) {
+                                apiMethod.addSignature(sig);
+                            }
+                            break;
+                        }
+                    }
+                }
+                // copy the option and override with the correct description
+                ApiOptionModel copy = ((ApiOptionModel) option).copy();
+                apiMethod.addApiOptionModel(copy);
+                // the option description is stored on @ApiMethod
+                copy.setDescription(method.description());
+                // whether we are consumer or producer only
+                group = EndpointHelper.labelAsGroupName(copy.getLabel(), api.isConsumerOnly(),
+                        api.isProducerOnly());
+                copy.setGroup(group);
+                copy.setOptional(apiParam.optional());
+            }
+        } else {
+            option.setKind("parameter");
+            if (componentModel.getEndpointOptions().stream().noneMatch(opt -> name.equals(opt.getName()))) {
+                componentModel.addEndpointOption((EndpointOptionModel) option);
+            }
+        }
+    }
+
+    private boolean collectUriPathProperties(ComponentModel componentModel, Class<?> classElement, Set<String> excludes, String prefix, String nestedTypeName, String nestedFieldName, boolean componentOption, Class<?> orgClassElement, Metadata metadata, Field fieldElement, boolean deprecated, String deprecationNote, Boolean secret) {
+        UriPath path = fieldElement.getAnnotation(UriPath.class);
+        String fieldName = fieldElement.getName();
+        // component options should not include @UriPath as they are for endpoints only
+        if (!componentOption && path != null) {
+            String name = prefix + (Strings.isNullOrEmpty(path.name()) ? fieldName : path.name());
+
+            // should we exclude the name?
+            if (excludes.contains(name)) {
+                return true;
+            }
+
+            Object defaultValue = path.defaultValue();
+            if ("".equals(defaultValue) && metadata != null) {
+                defaultValue = metadata.defaultValue();
+            }
+            String defaultValueNote = path.defaultValueNote();
+            boolean required = metadata != null && metadata.required();
+            String label = path.label();
+            if (Strings.isNullOrEmpty(label) && metadata != null) {
+                label = metadata.label();
+            }
+            String displayName = path.displayName();
+            if (Strings.isNullOrEmpty(displayName)) {
+                displayName = metadata != null ? metadata.displayName() : null;
+            }
+            // compute a display name if we don't have anything
+            if (Strings.isNullOrEmpty(displayName)) {
+                displayName = Strings.asTitle(name);
+            }
+
+            Class<?> fieldTypeElement = fieldElement.getType();
+            String fieldTypeName = getTypeName(GenericsUtil.resolveType(orgClassElement, fieldElement));
+
+            String docComment = path.description();
+            if (Strings.isNullOrEmpty(docComment)) {
+                docComment = findJavaDoc(fieldElement, fieldName, name, classElement, false);
+            }
+
+            // gather enums
+            List<String> enums = gatherEnums(path, fieldTypeElement);
+
+            // the field type may be overloaded by another type
+            boolean isDuration = false;
+            if (!Strings.isNullOrEmpty(path.javaType())) {
+                String mjt = path.javaType();
+                if ("java.time.Duration".equals(mjt)) {
+                    isDuration = true;
+                } else {
+                    fieldTypeName = mjt;
+                }
+            }
+
+            // prepare default value so its value is correct according to its type
+            defaultValue = getDefaultValue(defaultValue, fieldTypeName, isDuration);
+
+            boolean isSecret = secret != null && secret || path.secret();
+            boolean isAutowired = metadata != null && metadata.autowired();
+            String group = EndpointHelper.labelAsGroupName(label, componentModel.isConsumerOnly(),
+                    componentModel.isProducerOnly());
+
+            // generics for collection types
+            String nestedType = null;
+            String desc = fieldTypeName;
+            if (desc.contains("<") && desc.contains(">")) {
+                desc = Strings.between(desc, "<", ">");
+                // if it has additional nested types, then we only want the outer type
+                int pos = desc.indexOf('<');
+                if (pos != -1) {
+                    desc = desc.substring(0, pos);
+                }
+                // if its a map then it has a key/value, so we only want the last part
+                pos = desc.indexOf(',');
+                if (pos != -1) {
+                    desc = desc.substring(pos + 1);
+                }
+                desc = desc.replace('$', '.');
+                desc = desc.trim();
+                // skip if the type is generic or a wildcard
+                if (!desc.isEmpty() && desc.indexOf('?') == -1 && !desc.contains(" extends ")) {
+                    nestedType = desc;
+                }
+            }
+
+            BaseOptionModel option;
+            if (componentOption) {
+                option = new ComponentOptionModel();
+            } else {
+                option = new EndpointOptionModel();
+            }
+            option.setName(name);
+            option.setKind("path");
+            option.setDisplayName(displayName);
+            option.setType(getType(fieldTypeName, false, isDuration));
+            option.setJavaType(fieldTypeName);
+            option.setRequired(required);
+            option.setDefaultValue(defaultValue);
+            option.setDefaultValueNote(defaultValueNote);
+            option.setDescription(docComment.trim());
+            option.setDeprecated(deprecated);
+            option.setDeprecationNote(deprecationNote);
+            option.setSecret(isSecret);
+            option.setAutowired(isAutowired);
+            option.setGroup(group);
+            option.setLabel(label);
+            option.setEnums(enums);
+            option.setNestedType(nestedType);
+            option.setConfigurationClass(nestedTypeName);
+            option.setConfigurationField(nestedFieldName);
+            if (componentModel.getEndpointOptions().stream().noneMatch(opt -> name.equals(opt.getName()))) {
+                componentModel.addEndpointOption((EndpointOptionModel) option);
+            }
+        }
+        return false;
+    }
+
+    private void collectExcludes(Class<?> classElement, Set<String> excludes) {
+        final UriEndpoint uriEndpoint = classElement.getAnnotation(UriEndpoint.class);
+        if (uriEndpoint != null) {
+            String excludedProperties = getExcludedEnd(classElement.getAnnotation(Metadata.class));
+
+            Collections.addAll(excludes, excludedProperties.split(","));
+        }
+    }
+
     private static List<String> doGatherFromEnum(Class<?> fieldTypeElement) {
         final List<String> enums = new ArrayList<>();
 
@@ -1739,6 +1755,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         if (source != null && !jd.tags().isEmpty()) {
             ASTNode n = (ASTNode) jd.tags().get(0);
             String txt = source.substring(n.getStartPosition(), n.getStartPosition() + n.getLength());
+
             return txt
                     .replaceAll(" *\n *\\* *\n", "\n\n")
                     .replaceAll(" *\n *\\* +", "\n");


[camel] 04/04: CAMEL-17984: enable class caching for all other classes

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

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

commit 079a19a55d1102e4b0bf944542070290d7c532c5
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Thu Apr 14 17:20:22 2022 +0200

    CAMEL-17984: enable class caching for all other classes
---
 .../maven/packaging/AbstractGeneratorMojo.java     | 11 ++---
 .../packaging/EndpointSchemaGeneratorMojo.java     | 51 +++++++++++++---------
 2 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
index 07e00ce7e95..aeb36f8189a 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
@@ -25,8 +25,8 @@ import java.nio.file.attribute.BasicFileAttributes;
 import java.time.Duration;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Supplier;
 
 import org.apache.camel.tooling.util.FileUtil;
@@ -48,7 +48,7 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
     public static final String GENERATED_MSG = "Generated by camel build tools - do NOT edit this file!";
     public static final String NL = "\n";
 
-    private static final Map<String, Class<?>> KNOWN_CLASSES_CACHE = new HashMap<>();
+    private static final Map<String, Class<?>> KNOWN_CLASSES_CACHE = new ConcurrentHashMap<>();
 
     /**
      * The maven project.
@@ -188,12 +188,7 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
     }
 
     protected Class<?> loadClass(String loadClassName) {
-        final Class<?> ret = KNOWN_CLASSES_CACHE.get(loadClassName);
-        if (ret != null) {
-            return ret;
-        }
-
-        return doLoadClass(loadClassName);
+        return KNOWN_CLASSES_CACHE.computeIfAbsent(loadClassName, k -> doLoadClass(loadClassName));
     }
 
     private Class<?> doLoadClass(String loadClassName) {
diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
index 72eb4265594..dfcbbc88466 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
@@ -199,22 +199,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
             }
             final String aliasTitle = aTitle;
 
-            ComponentModel parentData = null;
-            Class<?> superclass = classElement.getSuperclass();
-            if (superclass != null) {
-                parentData = models.get(superclass);
-                if (parentData == null) {
-                    UriEndpoint parentUriEndpoint = superclass.getAnnotation(UriEndpoint.class);
-                    if (parentUriEndpoint != null) {
-                        String parentScheme = parentUriEndpoint.scheme().split(",")[0];
-                        String superClassName = superclass.getName();
-                        String packageName = superClassName.substring(0, superClassName.lastIndexOf('.'));
-                        String fileName = packageName.replace('.', '/') + "/" + parentScheme + ".json";
-                        String json = loadResource(fileName);
-                        parentData = JsonMapper.generateComponentModel(json);
-                    }
-                }
-            }
+            ComponentModel parentData = collectParentData(models, classElement);
 
             ComponentModel model = writeJSonSchemeAndPropertyConfigurer(classElement, uriEndpoint, aliasTitle, alias,
                     extendsAlias, label, schemes, parentData);
@@ -222,6 +207,28 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         }
     }
 
+    private ComponentModel collectParentData(Map<Class, ComponentModel> models, Class<?> classElement) {
+        ComponentModel parentData = null;
+        final Class<?> superclass = classElement.getSuperclass();
+
+        if (superclass != null) {
+            parentData = models.get(superclass);
+            if (parentData == null) {
+                UriEndpoint parentUriEndpoint = superclass.getAnnotation(UriEndpoint.class);
+                if (parentUriEndpoint != null) {
+                    String parentScheme = parentUriEndpoint.scheme().split(",")[0];
+                    String superClassName = superclass.getName();
+                    String packageName = superClassName.substring(0, superClassName.lastIndexOf('.'));
+                    String fileName = packageName.replace('.', '/') + "/" + parentScheme + ".json";
+                    String json = loadResource(fileName);
+                    parentData = JsonMapper.generateComponentModel(json);
+                }
+            }
+        }
+
+        return parentData;
+    }
+
     private int compareClasses(Class<?> c1, Class<?> c2) {
         if (c1.isAssignableFrom(c2)) {
             return -1;
@@ -676,6 +683,7 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
     private void generateComponentConfigurer(
             UriEndpoint uriEndpoint, String scheme, String[] schemes, ComponentModel componentModel,
             ComponentModel parentData) {
+
         if (!uriEndpoint.generateConfigurer()) {
             return;
         }
@@ -685,8 +693,9 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         }
         String pfqn;
         boolean hasSuper;
-        if (parentData != null
-                && loadClass(componentModel.getJavaType()).getSuperclass() == loadClass(parentData.getJavaType())) {
+
+        Class<?> superClazz = loadClass(componentModel.getJavaType()).getSuperclass();
+        if (parentData != null && superClazz.getName().equals(parentData.getJavaType())) {
             // special for activemq and amqp scheme which should reuse jms
             pfqn = parentData.getJavaType() + "Configurer";
             hasSuper = true;
@@ -734,10 +743,12 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         if (isFirstScheme(scheme, schemes)) {
             return;
         }
+
+        Class<?> superClazz = loadClass(componentModel.getJavaType()).getSuperclass();
+
         String pfqn;
         boolean hasSuper;
-        if (parentData != null
-                && loadClass(componentModel.getJavaType()).getSuperclass() == loadClass(parentData.getJavaType())) {
+        if (parentData != null && superClazz.getName().equals(parentData.getJavaType())) {
             try {
                 pfqn = classElement.getSuperclass().getName() + "Configurer";
                 hasSuper = true;


[camel] 01/04: CAMEL-17894: cache known Java classes

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

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

commit 2f22c70e605e285888cbbc1472561650ec529840
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Thu Apr 14 11:28:44 2022 +0200

    CAMEL-17894: cache known Java classes
    
    Avoid a complex flow that only loads certain Java classes after they
    thrown multiple NoClassDefFoundError.
    
    This should provide a small improvement to the build time
---
 .../maven/packaging/AbstractGeneratorMojo.java     | 39 ++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
index 457ecefb4d7..07e00ce7e95 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/AbstractGeneratorMojo.java
@@ -22,7 +22,11 @@ import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.time.Duration;
 import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.function.Supplier;
 
 import org.apache.camel.tooling.util.FileUtil;
@@ -44,6 +48,8 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
     public static final String GENERATED_MSG = "Generated by camel build tools - do NOT edit this file!";
     public static final String NL = "\n";
 
+    private static final Map<String, Class<?>> KNOWN_CLASSES_CACHE = new HashMap<>();
+
     /**
      * The maven project.
      */
@@ -64,6 +70,23 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
 
     private DynamicClassLoader projectClassLoader;
 
+    static {
+        KNOWN_CLASSES_CACHE.put("Byte", Byte.class);
+        KNOWN_CLASSES_CACHE.put("Boolean", Boolean.class);
+        KNOWN_CLASSES_CACHE.put("Date", Date.class);
+        KNOWN_CLASSES_CACHE.put("Double", Double.class);
+        KNOWN_CLASSES_CACHE.put("Duration", Duration.class);
+        KNOWN_CLASSES_CACHE.put("String", String.class);
+        KNOWN_CLASSES_CACHE.put("Integer", Integer.class);
+        KNOWN_CLASSES_CACHE.put("Long", Long.class);
+        KNOWN_CLASSES_CACHE.put("File", File.class);
+        KNOWN_CLASSES_CACHE.put("Object", Object.class);
+        KNOWN_CLASSES_CACHE.put("int", int.class);
+        KNOWN_CLASSES_CACHE.put("long", long.class);
+        KNOWN_CLASSES_CACHE.put("boolean", boolean.class);
+
+    }
+
     public void execute(
             MavenProject project,
             MavenProjectHelper projectHelper,
@@ -165,6 +188,15 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
     }
 
     protected Class<?> loadClass(String loadClassName) {
+        final Class<?> ret = KNOWN_CLASSES_CACHE.get(loadClassName);
+        if (ret != null) {
+            return ret;
+        }
+
+        return doLoadClass(loadClassName);
+    }
+
+    private Class<?> doLoadClass(String loadClassName) {
         Class<?> optionClass;
         String org = loadClassName;
         while (true) {
@@ -174,9 +206,16 @@ public abstract class AbstractGeneratorMojo extends AbstractMojo {
             } catch (ClassNotFoundException e) {
                 int dotIndex = loadClassName.lastIndexOf('.');
                 if (dotIndex == -1) {
+                    if (getLog().isDebugEnabled()) {
+                        getLog().debug("Failed to load class: " + loadClassName);
+                    }
+
                     throw new NoClassDefFoundError(org);
                 } else {
                     loadClassName = loadClassName.substring(0, dotIndex) + "$" + loadClassName.substring(dotIndex + 1);
+                    if (getLog().isDebugEnabled()) {
+                        getLog().debug("Relocating previous class name for loading as: " + loadClassName);
+                    }
                 }
             }
         }


[camel] 02/04: CAMEL-17894: avoid logging and formatting strings in plugin hot path

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

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

commit a00e749272812d1bc90b25db3019ad520947aab4
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Thu Apr 14 12:42:43 2022 +0200

    CAMEL-17894: avoid logging and formatting strings in plugin hot path
---
 .../packaging/EndpointSchemaGeneratorMojo.java     | 47 +++++++++++++++-------
 1 file changed, 32 insertions(+), 15 deletions(-)

diff --git a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
index ce2dfa8f1cb..b2cad0e7c50 100644
--- a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
+++ b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/EndpointSchemaGeneratorMojo.java
@@ -343,18 +343,24 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         for (Field field : headersClass.getFields()) {
             if ((isEnum || isStatic(field.getModifiers()) && field.getType() == String.class)
                     && field.isAnnotationPresent(Metadata.class)) {
-                getLog().debug(
-                        String.format("Trying to add the constant %s in the class %s as header.", field.getName(),
-                                headersClass.getName()));
+
+                if (getLog().isDebugEnabled()) {
+                    getLog().debug(
+                            String.format("Trying to add the constant %s in the class %s as header.", field.getName(),
+                                    headersClass.getName()));
+                }
                 if (addEndpointHeader(componentModel, scheme, field, headersNameProvider)) {
                     foundHeader = true;
                     continue;
                 }
             }
-            getLog().debug(
-                    String.format(
-                            "The field %s of the class %s is not considered as a name of a header, thus it is skipped",
-                            field.getName(), headersClass.getName()));
+
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(
+                        String.format(
+                                "The field %s of the class %s is not considered as a name of a header, thus it is skipped",
+                                field.getName(), headersClass.getName()));
+            }
         }
         return foundHeader;
     }
@@ -376,14 +382,20 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
     private boolean addEndpointHeader(ComponentModel componentModel, String scheme, Field field, String headersNameProvider) {
         final Metadata metadata = field.getAnnotation(Metadata.class);
         if (metadata == null) {
-            getLog().debug(String.format("The field %s in class %s has no Metadata", field.getName(),
-                    field.getDeclaringClass().getName()));
+
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(String.format("The field %s in class %s has no Metadata", field.getName(),
+                        field.getDeclaringClass().getName()));
+            }
             return false;
         }
         final String[] applicableFor = metadata.applicableFor();
         if (applicableFor.length > 0 && Arrays.stream(applicableFor).noneMatch(s -> s.equals(scheme))) {
-            getLog().debug(String.format("The field %s in class %s is not applicable for %s", field.getName(),
-                    field.getDeclaringClass().getName(), scheme));
+
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(String.format("The field %s in class %s is not applicable for %s", field.getName(),
+                        field.getDeclaringClass().getName(), scheme));
+            }
             return false;
         }
         final EndpointHeaderModel header = new EndpointHeaderModel();
@@ -406,15 +418,20 @@ public class EndpointSchemaGeneratorMojo extends AbstractGeneratorMojo {
         try {
             header.setEnums(getEnums(metadata, header.getJavaType().isEmpty() ? null : loadClass(header.getJavaType())));
         } catch (NoClassDefFoundError e) {
-            getLog().debug(String.format("The java type %s could not be found", header.getJavaType()), e);
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(String.format("The java type %s could not be found", header.getJavaType()), e);
+            }
         }
         try {
             setHeaderNames(header, field, headersNameProvider);
             componentModel.addEndpointHeader(header);
         } catch (Exception e) {
-            getLog().debug(String.format("The name of the header corresponding to the field %s in class %s cannot be retrieved",
-                    field.getName(),
-                    field.getDeclaringClass().getName()));
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(
+                        String.format("The name of the header corresponding to the field %s in class %s cannot be retrieved",
+                                field.getName(),
+                                field.getDeclaringClass().getName()));
+            }
         }
         return true;
     }