[ 
https://issues.apache.org/jira/browse/CAMEL-11675?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16537525#comment-16537525
 ] 

ASF GitHub Bot commented on CAMEL-11675:
----------------------------------------

onderson closed pull request #2391: CAMEL-11675 - Repetable @Metadata 
annotation and amend apt for tooling
URL: https://github.com/apache/camel/pull/2391
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessor.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessor.java
index 4b66859ace6..e5f93648ece 100644
--- 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessor.java
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/CoreEipAnnotationProcessor.java
@@ -219,8 +219,8 @@ protected EipModel 
findEipModelProperties(ProcessingEnvironment processingEnv, R
         boolean deprecated = classElement.getAnnotation(Deprecated.class) != 
null;
         model.setDeprecated(deprecated);
 
-        Metadata metadata = classElement.getAnnotation(Metadata.class);
-        if (metadata != null) {
+        Metadata[] metadataArray = 
classElement.getAnnotationsByType(Metadata.class);
+        for (Metadata metadata : metadataArray) {
             if (!Strings.isNullOrEmpty(metadata.label())) {
                 model.setLabel(metadata.label());
             }
@@ -348,54 +348,56 @@ private boolean processAttribute(ProcessingEnvironment 
processingEnv, RoundEnvir
             }
         }
 
-        Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-
         name = prefix + name;
         TypeMirror fieldType = fieldElement.asType();
         String fieldTypeName = fieldType.toString();
         TypeElement fieldTypeElement = findTypeElement(processingEnv, 
roundEnv, fieldTypeName);
-
+        
         String defaultValue = findDefaultValue(fieldElement, fieldTypeName);
         String docComment = findJavaDoc(elementUtils, fieldElement, fieldName, 
name, classElement, true);
         boolean required = attribute.required();
         // metadata may overrule element required
         required = findRequired(fieldElement, required);
-
+        
+        String displayName = null;
+        String deprecationNote = null;
         // gather enums
         Set<String> enums = new TreeSet<>();
-        boolean isEnum;
-        if (metadata != null && !Strings.isNullOrEmpty(metadata.enums())) {
-            isEnum = true;
-            String[] values = metadata.enums().split(",");
-            for (String val : values) {
-                enums.add(val);
-            }
-        } else {
-            isEnum = fieldTypeElement != null && fieldTypeElement.getKind() == 
ElementKind.ENUM;
-            if (isEnum) {
-                TypeElement enumClass = findTypeElement(processingEnv, 
roundEnv, fieldTypeElement.asType().toString());
-                if (enumClass != null) {
-                    // find all the enum constants which has the possible enum 
value that can be used
-                    List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
-                    for (VariableElement var : fields) {
-                        if (var.getKind() == ElementKind.ENUM_CONSTANT) {
-                            String val = var.toString();
-                            enums.add(val);
+        boolean isEnum = false;
+        Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+        for (Metadata metadata : metadataArray) {
+            
+            if (!Strings.isNullOrEmpty(metadata.enums())) {
+                isEnum = true;
+                String[] values = metadata.enums().split(",");
+                for (String val : values) {
+                    enums.add(val);
+                }
+            } else {
+                isEnum = fieldTypeElement != null && 
fieldTypeElement.getKind() == ElementKind.ENUM;
+                if (isEnum) {
+                    TypeElement enumClass = findTypeElement(processingEnv, 
roundEnv, fieldTypeElement.asType().toString());
+                    if (enumClass != null) {
+                        // find all the enum constants which has the possible 
enum value that can be used
+                        List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+                        for (VariableElement var : fields) {
+                            if (var.getKind() == ElementKind.ENUM_CONSTANT) {
+                                String val = var.toString();
+                                enums.add(val);
+                            }
                         }
                     }
                 }
             }
+            if (metadata.displayName() != null) {
+                displayName = metadata.displayName();
+            }
+            if (metadata.deprecationNode() != null) {
+                deprecationNote = metadata.deprecationNode();
+            }
         }
-
-        String displayName = null;
-        if (metadata != null) {
-            displayName = metadata.displayName();
-        }
+        
         boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != 
null;
-        String deprecationNote = null;
-        if (metadata != null) {
-            deprecationNote = metadata.deprecationNode();
-        }
 
         EipOption ep = new EipOption(name, displayName, "attribute", 
fieldTypeName, required, defaultValue, docComment, deprecated, deprecationNote, 
isEnum, enums, false, null, false);
         eipOptions.add(ep);
@@ -429,16 +431,19 @@ private void processValue(ProcessingEnvironment 
processingEnv, RoundEnvironment
         required = findRequired(fieldElement, required);
 
         String displayName = null;
-        Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-        if (metadata != null) {
-            displayName = metadata.displayName();
-        }
-        boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != 
null;
         String deprecationNote = null;
-        if (metadata != null) {
-            deprecationNote = metadata.deprecationNode();
+        Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+        for (Metadata metadata : metadataArray) {
+            if (metadata.displayName() != null) {
+                displayName = metadata.displayName();
+            }
+            if (metadata.deprecationNode() != null) {
+                deprecationNote = metadata.deprecationNode();
+            }
         }
 
+        boolean deprecated = fieldElement.getAnnotation(Deprecated.class) != 
null;  
+
         EipOption ep = new EipOption(name, displayName, "value", 
fieldTypeName, required, defaultValue, docComment, deprecated, deprecationNote, 
false, null, false, null, false);
         eipOptions.add(ep);
     }
@@ -451,8 +456,6 @@ private void processElement(ProcessingEnvironment 
processingEnv, RoundEnvironmen
         fieldName = fieldElement.getSimpleName().toString();
         if (element != null) {
 
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-
             String kind = "element";
             String name = element.name();
             if (isNullOrEmpty(name) || "##default".equals(name)) {
@@ -474,27 +477,38 @@ private void processElement(ProcessingEnvironment 
processingEnv, RoundEnvironmen
             if (!asPredicate) {
                 asPredicate = classElement.getAnnotation(AsPredicate.class) != 
null;
             }
-
-            // gather enums
+            
+            String displayName = null;
+            String deprecationNote = null;
+            boolean isEnum = false;
             Set<String> enums = new TreeSet<>();
-            boolean isEnum;
-            if (metadata != null && !Strings.isNullOrEmpty(metadata.enums())) {
-                isEnum = true;
-                String[] values = metadata.enums().split(",");
-                for (String val : values) {
-                    enums.add(val);
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
                 }
-            } else {
-                isEnum = fieldTypeElement != null && 
fieldTypeElement.getKind() == ElementKind.ENUM;
-                if (isEnum) {
-                    TypeElement enumClass = findTypeElement(processingEnv, 
roundEnv, fieldTypeElement.asType().toString());
-                    if (enumClass != null) {
-                        // find all the enum constants which has the possible 
enum value that can be used
-                        List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
-                        for (VariableElement var : fields) {
-                            if (var.getKind() == ElementKind.ENUM_CONSTANT) {
-                                String val = var.toString();
-                                enums.add(val);
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
+                // gather enums
+                if (metadata != null && 
!Strings.isNullOrEmpty(metadata.enums())) {
+                    isEnum = true;
+                    String[] values = metadata.enums().split(",");
+                    for (String val : values) {
+                        enums.add(val);
+                    }
+                } else {
+                    isEnum = fieldTypeElement != null && 
fieldTypeElement.getKind() == ElementKind.ENUM;
+                    if (isEnum) {
+                        TypeElement enumClass = findTypeElement(processingEnv, 
roundEnv, fieldTypeElement.asType().toString());
+                        if (enumClass != null) {
+                            // find all the enum constants which has the 
possible enum value that can be used
+                            List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+                            for (VariableElement var : fields) {
+                                if (var.getKind() == 
ElementKind.ENUM_CONSTANT) {
+                                    String val = var.toString();
+                                    enums.add(val);
+                                }
                             }
                         }
                     }
@@ -531,15 +545,7 @@ private void processElement(ProcessingEnvironment 
processingEnv, RoundEnvironmen
                 oneOfTypes.add("otherwise");
             }
 
-            String displayName = null;
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
             boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
-            String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
-            }
 
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, required, defaultValue, docComment, deprecated, deprecationNote, 
isEnum, enums, isOneOf, oneOfTypes, asPredicate);
             eipOptions.add(ep);
@@ -572,18 +578,21 @@ private void processElements(ProcessingEnvironment 
processingEnv, RoundEnvironme
                 String child = element.name();
                 oneOfTypes.add(child);
             }
-
+            
             String displayName = null;
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
-            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
+                }
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
             }
 
+            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
+
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, required, defaultValue, docComment, deprecated, deprecationNote, 
false, null, true, oneOfTypes, false);
             eipOptions.add(ep);
         }
@@ -811,16 +820,20 @@ private void processOutputs(ProcessingEnvironment 
processingEnv, RoundEnvironmen
 
             // remove some types which are not intended as an output in eips
             oneOfTypes.remove("route");
+
             String displayName = null;
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
-            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
+                }
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
             }
+            
+            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
 
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, true, "", "", deprecated, deprecationNote, false, null, true, 
oneOfTypes, false);
             eipOptions.add(ep);
@@ -863,16 +876,20 @@ private void processVerbs(ProcessingEnvironment 
processingEnv, RoundEnvironment
                     }
                 }
             }
+            
             String displayName = null;
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
-            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
+                }
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
             }
+            
+            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
 
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, true, "", docComment, deprecated, deprecationNote, false, null, 
true, oneOfTypes, false);
             eipOptions.add(ep);
@@ -925,18 +942,21 @@ private void processRefExpression(ProcessingEnvironment 
processingEnv, RoundEnvi
                     }
                 }
             }
-
+            
             String displayName = null;
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
-            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
+                }
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
             }
 
+            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
+
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, true, "", docComment, deprecated, deprecationNote, false, null, 
true, oneOfTypes, asPredicate);
             eipOptions.add(ep);
         }
@@ -970,15 +990,18 @@ private void processRefWhenClauses(ProcessingEnvironment 
processingEnv, RoundEnv
             boolean asPredicate = true;
 
             String displayName = null;
-            Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-            if (metadata != null) {
-                displayName = metadata.displayName();
-            }
-            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
             String deprecationNote = null;
-            if (metadata != null) {
-                deprecationNote = metadata.deprecationNode();
+            Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+            for (Metadata metadata : metadataArray) {
+                if (metadata.displayName() != null) {
+                    displayName = metadata.displayName();
+                }
+                if (metadata.deprecationNode() != null) {
+                    deprecationNote = metadata.deprecationNode();
+                }
             }
+            
+            boolean deprecated = fieldElement.getAnnotation(Deprecated.class) 
!= null;
 
             EipOption ep = new EipOption(name, displayName, kind, 
fieldTypeName, false, "", docComment, deprecated, deprecationNote, false, null, 
true, oneOfTypes, asPredicate);
             eipOptions.add(ep);
@@ -997,12 +1020,13 @@ private boolean supportOutputs(TypeElement classElement) 
{
 
     private String findDefaultValue(VariableElement fieldElement, String 
fieldTypeName) {
         String defaultValue = null;
-        Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-        if (metadata != null) {
+        Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+        for (Metadata metadata : metadataArray) {
             if (!Strings.isNullOrEmpty(metadata.defaultValue())) {
                 defaultValue = metadata.defaultValue();
             }
         }
+
         if (defaultValue == null) {
             // if its a boolean type, then we use false as the default
             if ("boolean".equals(fieldTypeName) || 
"java.lang.Boolean".equals(fieldTypeName)) {
@@ -1014,8 +1038,8 @@ private String findDefaultValue(VariableElement 
fieldElement, String fieldTypeNa
     }
 
     private boolean findRequired(VariableElement fieldElement, boolean 
defaultValue) {
-        Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-        if (metadata != null) {
+        Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+        for (Metadata metadata : metadataArray) {
             if (!Strings.isNullOrEmpty(metadata.required())) {
                 defaultValue = "true".equals(metadata.required());
             }
diff --git 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
index bd603a7dc7d..03ff2a3997e 100644
--- 
a/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
+++ 
b/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
@@ -359,12 +359,22 @@ protected ComponentModel 
findComponentProperties(RoundEnvironment roundEnv, UriE
         model.setLenientProperties(uriEndpoint.lenientProperties());
         model.setAsync(implementsInterface(processingEnv, roundEnv, 
endpointClassElement, "org.apache.camel.AsyncEndpoint"));
 
+        String deprecationNote = null;
         // what is the first version this component was added to Apache Camel
         String firstVersion = uriEndpoint.firstVersion();
-        if (Strings.isNullOrEmpty(firstVersion) && 
endpointClassElement.getAnnotation(Metadata.class) != null) {
-            // fallback to @Metadata if not from @UriEndpoint
-            firstVersion = 
endpointClassElement.getAnnotation(Metadata.class).firstVersion();
+        Metadata[] metadataArray = 
endpointClassElement.getAnnotationsByType(Metadata.class);
+        for(Metadata metadata : metadataArray) {
+               if (Strings.isNullOrEmpty(firstVersion)) {
+                // fallback to @Metadata if not from @UriEndpoint
+                       if (metadata.firstVersion() != null) {
+                               firstVersion = metadata.firstVersion();
+                }
+                if (metadata.deprecationNode() != null) {
+                       deprecationNote = metadata.deprecationNode();
+                }
+            }
         }
+
         if (!Strings.isNullOrEmpty(firstVersion)) {
             model.setFirstVersion(firstVersion);
         }
@@ -395,11 +405,7 @@ protected ComponentModel 
findComponentProperties(RoundEnvironment roundEnv, UriE
                 deprecated = name != null && name.contains("(deprecated)");
             }
             model.setDeprecated(deprecated);
-
-            String deprecationNote = null;
-            if (endpointClassElement.getAnnotation(Metadata.class) != null) {
-                deprecationNote = 
endpointClassElement.getAnnotation(Metadata.class).deprecationNode();
-            }
+                
             model.setDeprecationNode(deprecationNote);
 
             if (map.containsKey("groupId")) {
@@ -441,19 +447,25 @@ protected void findComponentClassProperties(PrintWriter 
writer, RoundEnvironment
                                                 Set<ComponentOption> 
componentOptions, TypeElement classElement, String prefix) {
         Elements elementUtils = processingEnv.getElementUtils();
         while (true) {
-            Metadata componentAnnotation = 
classElement.getAnnotation(Metadata.class);
-            if (componentAnnotation != null && Objects.equals("verifiers", 
componentAnnotation.label())) {
-                componentModel.setVerifiers(componentAnnotation.enums());
+            Metadata[] componentAnnotationArray = 
classElement.getAnnotationsByType(Metadata.class);
+            for(Metadata componentAnnotation : componentAnnotationArray) {
+                if (componentAnnotation != null && Objects.equals("verifiers", 
componentAnnotation.label())) {
+                       if (componentAnnotation.enums() != null) {
+                       
componentModel.setVerifiers(componentAnnotation.enums());
+                    }
+                }
             }
 
             List<ExecutableElement> methods = 
ElementFilter.methodsIn(classElement.getEnclosedElements());
             for (ExecutableElement method : methods) {
                 String methodName = method.getSimpleName().toString();
                 boolean deprecated = method.getAnnotation(Deprecated.class) != 
null;
-                Metadata metadata = method.getAnnotation(Metadata.class);
                 String deprecationNote = null;
-                if (metadata != null) {
-                    deprecationNote = metadata.deprecationNode();
+                Metadata[] metadataArray = 
method.getAnnotationsByType(Metadata.class);
+                for(Metadata metadata : metadataArray) {
+                       if (metadata.deprecationNode() != null) {
+                       deprecationNote = metadata.deprecationNode();
+                    }
                 }
 
                 // must be the setter
@@ -474,71 +486,83 @@ protected void findComponentClassProperties(PrintWriter 
writer, RoundEnvironment
 
                 // we usually favor putting the @Metadata annotation on the 
field instead of the setter, so try to use it if its there
                 VariableElement field = findFieldElement(classElement, 
fieldName);
-                if (field != null && metadata == null) {
-                    metadata = field.getAnnotation(Metadata.class);
+                if (field != null && metadataArray.length == 0) {
+                       metadataArray = 
field.getAnnotationsByType(Metadata.class);
                 }
-
-                String required = metadata != null ? metadata.required() : 
null;
-                String label = metadata != null ? metadata.label() : null;
-                boolean secret = metadata != null && metadata.secret();
-                String displayName = metadata != null ? metadata.displayName() 
: null;
-
-                // we do not yet have default values / notes / as no 
annotation support yet
-                // String defaultValueNote = param.defaultValueNote();
-                String defaultValue = metadata != null ? 
metadata.defaultValue() : null;
-                String defaultValueNote = null;
-
+                
                 ExecutableElement setter = method;
                 String name = fieldName;
                 name = prefix + name;
                 TypeMirror fieldType = setter.getParameters().get(0).asType();
                 String fieldTypeName = fieldType.toString();
                 TypeElement fieldTypeElement = findTypeElement(processingEnv, 
roundEnv, fieldTypeName);
-
+                
                 String docComment = findJavaDoc(elementUtils, method, 
fieldName, name, classElement, false);
-                if (isNullOrEmpty(docComment)) {
-                    docComment = metadata != null ? metadata.description() : 
null;
-                }
-                if (isNullOrEmpty(docComment)) {
-                    // apt cannot grab javadoc from camel-core, only from 
annotations
-                    if ("setHeaderFilterStrategy".equals(methodName)) {
-                        docComment = HEADER_FILTER_STRATEGY_JAVADOC;
-                    } else {
-                        docComment = "";
-                    }
-                }
 
+                // we do not yet have default values / notes / as no 
annotation support yet
+                // String defaultValueNote = param.defaultValueNote();
+                String required = null, label = null, displayName = null, 
defaultValue = null, defaultValueNote = null;
+                boolean secret = false;
                 // gather enums
                 Set<String> enums = new LinkedHashSet<>();
+                boolean isEnum = false;
+                for(Metadata metadata : metadataArray) {
+                       if (metadata.required() != null) {
+                               required = metadata.required();
+                    }
+                       if (metadata.label() != null) {
+                               label = metadata.label();
+                    }
+                    secret = metadata.secret();
+                    if (metadata.displayName() != null) {
+                       displayName = metadata.displayName();
+                    }
 
-                boolean isEnum;
-                if (metadata != null && 
!Strings.isNullOrEmpty(metadata.enums())) {
-                    isEnum = true;
-                    String[] values = metadata.enums().split(",");
-                    for (String val : values) {
-                        enums.add(val);
+                    if (metadata.defaultValue() != null) {
+                       defaultValue = metadata.defaultValue();
                     }
-                } else {
-                    isEnum = fieldTypeElement != null && 
fieldTypeElement.getKind() == ElementKind.ENUM;
-                    if (isEnum) {
-                        TypeElement enumClass = findTypeElement(processingEnv, 
roundEnv, fieldTypeElement.asType().toString());
-                        if (enumClass != null) {
-                            // find all the enum constants which has the 
possible enum value that can be used
-                            List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
-                            for (VariableElement var : fields) {
-                                if (var.getKind() == 
ElementKind.ENUM_CONSTANT) {
-                                    String val = var.toString();
-                                    enums.add(val);
+
+                    if (metadata.description() != null && 
isNullOrEmpty(docComment)) {
+                       docComment = metadata.description();
+                    }
+                    if (isNullOrEmpty(docComment)) {
+                        // apt cannot grab javadoc from camel-core, only from 
annotations
+                        if ("setHeaderFilterStrategy".equals(methodName)) {
+                            docComment = HEADER_FILTER_STRATEGY_JAVADOC;
+                        } else {
+                            docComment = "";
+                        }
+                    }
+
+                    if (!Strings.isNullOrEmpty(metadata.enums())) {
+                        isEnum = true;
+                        String[] values = metadata.enums().split(",");
+                        for (String val : values) {
+                            enums.add(val);
+                        }
+                    } else {
+                        isEnum = fieldTypeElement != null && 
fieldTypeElement.getKind() == ElementKind.ENUM;
+                        if (isEnum) {
+                            TypeElement enumClass = 
findTypeElement(processingEnv, roundEnv, fieldTypeElement.asType().toString());
+                            if (enumClass != null) {
+                                // find all the enum constants which has the 
possible enum value that can be used
+                                List<VariableElement> fields = 
ElementFilter.fieldsIn(enumClass.getEnclosedElements());
+                                for (VariableElement var : fields) {
+                                    if (var.getKind() == 
ElementKind.ENUM_CONSTANT) {
+                                        String val = var.toString();
+                                        enums.add(val);
+                                    }
                                 }
                             }
                         }
                     }
-                }
 
-                // the field type may be overloaded by another type
-                if (metadata != null && 
!Strings.isNullOrEmpty(metadata.javaType())) {
-                    fieldTypeName = metadata.javaType();
+                    // the field type may be overloaded by another type
+                    if (!Strings.isNullOrEmpty(metadata.javaType())) {
+                        fieldTypeName = metadata.javaType();
+                    }
                 }
+                
 
                 String group = EndpointHelper.labelAsGroupName(label, 
componentModel.isConsumerOnly(), componentModel.isProducerOnly());
                 ComponentOption option = new ComponentOption(name, 
displayName, fieldTypeName, required, defaultValue, defaultValueNote,
@@ -569,18 +593,43 @@ protected void findClassProperties(PrintWriter writer, 
RoundEnvironment roundEnv
             List<VariableElement> fieldElements = 
ElementFilter.fieldsIn(classElement.getEnclosedElements());
             for (VariableElement fieldElement : fieldElements) {
 
-                Metadata metadata = fieldElement.getAnnotation(Metadata.class);
-                boolean deprecated = 
fieldElement.getAnnotation(Deprecated.class) != null;
-                String deprecationNote = null;
-                if (metadata != null) {
-                    deprecationNote = metadata.deprecationNode();
-                }
-                Boolean secret = metadata != null ? metadata.secret() : null;
+               UriPath path = fieldElement.getAnnotation(UriPath.class);
+               Boolean secret = Boolean.FALSE;
+               Metadata[] metadataArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+                String deprecationNote = null, required = null, label = (path 
!= null ?  path.label() : null);
+                String defaultValue = (path != null ?  path.defaultValue() : 
null);
+                String displayName = (path != null ?  path.displayName() : 
null);
+                for(Metadata metadata : metadataArray) {
+                       if (metadata.deprecationNode() != null) {
+                               deprecationNote = metadata.deprecationNode();
+                    }
+                       secret = metadata.secret();
+                       if (metadata.required() != null) {
+                               required = metadata.required();
+                    }
+                    if (Strings.isNullOrEmpty(defaultValue)) {
+                       if (metadata.defaultValue() != null) {
+                               defaultValue = metadata.defaultValue();
+                        }
+                    }
 
-                UriPath path = fieldElement.getAnnotation(UriPath.class);
+                    if (Strings.isNullOrEmpty(label)) {
+                       if (metadata.label() != null) {
+                               label = metadata.label();
+                        }
+                    }
+                    if (Strings.isNullOrEmpty(displayName)) {
+                       if (metadata.displayName() != null) {
+                               displayName = metadata.displayName();
+                        }
+                    }
+                }
                 String fieldName = fieldElement.getSimpleName().toString();
+                String fieldTypeName = fieldElement.asType().toString();
+                boolean deprecated = 
fieldElement.getAnnotation(Deprecated.class) != null;
+
                 if (path != null) {
-                    String name = path.name();
+                       String name = path.name();
                     if (isNullOrEmpty(name)) {
                         name = fieldName;
                     }
@@ -590,33 +639,20 @@ protected void findClassProperties(PrintWriter writer, 
RoundEnvironment roundEnv
                     if (excludeProperty(excludeProperties, name)) {
                         continue;
                     }
+                   
 
-                    String defaultValue = path.defaultValue();
-                    if (Strings.isNullOrEmpty(defaultValue) && metadata != 
null) {
-                        defaultValue = metadata.defaultValue();
-                    }
-                    String required = metadata != null ? metadata.required() : 
null;
-                    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;
-                    }
-
-                    TypeMirror fieldType = fieldElement.asType();
-                    String fieldTypeName = fieldType.toString();
                     TypeElement fieldTypeElement = 
findTypeElement(processingEnv, roundEnv, fieldTypeName);
+                    // the field type may be overloaded by another type
+                    if (!Strings.isNullOrEmpty(path.javaType())) {
+                        fieldTypeName = path.javaType();
+                    }
 
                     String docComment = findJavaDoc(elementUtils, 
fieldElement, fieldName, name, classElement, false);
                     if (isNullOrEmpty(docComment)) {
                         docComment = path.description();
                     }
-
                     // gather enums
                     Set<String> enums = new LinkedHashSet<>();
-
                     boolean isEnum;
                     if (!Strings.isNullOrEmpty(path.enums())) {
                         isEnum = true;
@@ -639,15 +675,11 @@ protected void findClassProperties(PrintWriter writer, 
RoundEnvironment roundEnv
                                 }
                             }
                         }
-                    }
+                    }                    
 
-                    // the field type may be overloaded by another type
-                    if (!Strings.isNullOrEmpty(path.javaType())) {
-                        fieldTypeName = path.javaType();
-                    }
+                    boolean isSecret = secret != null ? secret : false;
 
                     String group = EndpointHelper.labelAsGroupName(label, 
componentModel.isConsumerOnly(), componentModel.isProducerOnly());
-                    boolean isSecret = secret != null ? secret : false;
                     EndpointPath ep = new EndpointPath(name, displayName, 
fieldTypeName, required, defaultValue, docComment, deprecated, deprecationNote,
                         isSecret, group, label, isEnum, enums);
                     endpointPaths.add(ep);
@@ -655,6 +687,31 @@ protected void findClassProperties(PrintWriter writer, 
RoundEnvironment roundEnv
 
                 UriParam param = fieldElement.getAnnotation(UriParam.class);
                 fieldName = fieldElement.getSimpleName().toString();
+                String defaultValueNote = ( param != null ? 
param.defaultValueNote() : null);
+                label = (param != null ?  param.label() : null);
+                defaultValue = (param != null ?  param.defaultValue() : null);
+                displayName = (param != null ?  param.displayName() : null);
+                Metadata[] metadataParamArray = 
fieldElement.getAnnotationsByType(Metadata.class);
+                for(Metadata metadata : metadataParamArray) {
+                       if (metadata.required() != null) {
+                               required = metadata.required();
+                    }
+                    if (Strings.isNullOrEmpty(defaultValue)) {
+                       if (metadata.defaultValue() != null) {
+                               defaultValue = metadata.defaultValue();
+                        }
+                    }
+                    if (Strings.isNullOrEmpty(label)) {
+                       if (metadata.label() != null) {
+                               label = metadata.label();
+                        }
+                    }
+                    if (Strings.isNullOrEmpty(displayName)) {
+                       if (metadata.displayName() != null) {
+                               displayName = metadata.displayName();
+                        }
+                    }
+                }
                 if (param != null) {
                     String name = param.name();
                     if (isNullOrEmpty(name)) {
@@ -670,24 +727,9 @@ protected void findClassProperties(PrintWriter writer, 
RoundEnvironment roundEnv
                     String paramOptionalPrefix = param.optionalPrefix();
                     String paramPrefix = param.prefix();
                     boolean multiValue = param.multiValue();
-                    String defaultValue = param.defaultValue();
-                    if (defaultValue == null && metadata != null) {
-                        defaultValue = metadata.defaultValue();
-                    }
-                    String defaultValueNote = param.defaultValueNote();
-                    String required = metadata != null ? metadata.required() : 
null;
-                    String label = param.label();
-                    if (Strings.isNullOrEmpty(label) && metadata != null) {
-                        label = metadata.label();
-                    }
-                    String displayName = param.displayName();
-                    if (Strings.isNullOrEmpty(displayName)) {
-                        displayName = metadata != null ? 
metadata.displayName() : null;
-                    }
 
                     // if the field type is a nested parameter then iterate 
through its fields
-                    TypeMirror fieldType = fieldElement.asType();
-                    String fieldTypeName = fieldType.toString();
+                    fieldTypeName = fieldElement.asType().toString();
                     TypeElement fieldTypeElement = 
findTypeElement(processingEnv, roundEnv, fieldTypeName);
                     UriParams fieldParams = null;
                     if (fieldTypeElement != null) {
diff --git 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
index 23c83b6b061..598d934fb09 100644
--- a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
+++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadata.java
@@ -18,6 +18,7 @@
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
@@ -30,6 +31,7 @@
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
+@Repeatable(Metadatas.class)
 public @interface Metadata {
 
     /**
diff --git 
a/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadatas.java 
b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadatas.java
new file mode 100644
index 00000000000..cc0ef6e2873
--- /dev/null
+++ b/tooling/spi-annotations/src/main/java/org/apache/camel/spi/Metadatas.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
+public @interface Metadatas {
+    Metadata[] value();
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


> @Metadata should be repeatable
> ------------------------------
>
>                 Key: CAMEL-11675
>                 URL: https://issues.apache.org/jira/browse/CAMEL-11675
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-core
>            Reporter: Luca Burgazzoli
>            Priority: Minor
>             Fix For: 2.23.0
>
>
> As today @Metadata is not repeatable so it is not easy to add multiple 
> information to i.e. a component, it would be nice to write something like:
> {code:java}
> @Metadata(key = "platforms", enums = { "spring", "spring-boot", "osgi" })
> @Metadata(key = "extensions", types = { MyExtension.cass })
> class MyComponent extends DefaultComponent {
> }
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to