jaykataria1111 commented on code in PR #3195:
URL: https://github.com/apache/logging-log4j2/pull/3195#discussion_r1862957803


##########
log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/processor/PluginProcessor.java:
##########
@@ -107,6 +123,93 @@ public boolean process(final Set<? extends TypeElement> 
annotations, final Round
         return false;
     }
 
+    private void processBuilderAttributes(final Iterable<? extends Element> 
elements) {
+        for (final Element element : elements) {
+            if (element instanceof VariableElement) {
+                processBuilderAttributes((VariableElement) element);
+            }
+        }
+    }
+
+    private void processBuilderAttributes(final VariableElement element) {
+        final String fieldName = element.getSimpleName().toString(); // 
Getting the name of the field
+        SuppressWarnings suppress = 
element.getAnnotation(SuppressWarnings.class);
+        if (suppress != null && 
Arrays.asList(suppress.value()).contains(SUPPRESS_WARNING_PUBLIC_SETTER_STRING))
 {
+            // Suppress the warning due to annotation
+            return;
+        }
+        final Element enclosingElement = element.getEnclosingElement();
+        // `element is a field
+        if (enclosingElement instanceof TypeElement) {
+            final TypeElement typeElement = (TypeElement) enclosingElement;
+            // Check the siblings of the field
+            for (final Element enclosedElement : 
typeElement.getEnclosedElements()) {
+                // `enclosedElement is a method or constructor
+                if (enclosedElement instanceof ExecutableElement) {
+                    final ExecutableElement methodElement = 
(ExecutableElement) enclosedElement;
+                    final String methodName = 
methodElement.getSimpleName().toString();
+
+                    if ((methodName.toLowerCase(Locale.ROOT).startsWith("set") 
// Typical pattern for setters
+                                    || methodName
+                                            .toLowerCase(Locale.ROOT)
+                                            .startsWith("with")) // Typical 
pattern for setters
+                            && methodElement.getParameters().size()
+                                    == 1 // It is a weird pattern to not have 
public setter
+                    ) {
+
+                        Types typeUtils = processingEnv.getTypeUtils();
+
+                        boolean followsNamePattern = methodName.equals(
+                                        String.format("set%s", 
expectedFieldNameInASetter(fieldName)))
+                                || methodName.equals(String.format("with%s", 
expectedFieldNameInASetter(fieldName)));
+
+                        // Check if method is public
+                        boolean isPublicMethod = 
methodElement.getModifiers().contains(Modifier.PUBLIC);
+
+                        // Check if the return type of the method element is 
Assignable.
+                        // Assuming it is a builder class the type of it 
should be assignable to its parent
+                        boolean checkForAssignable = typeUtils.isAssignable(
+                                methodElement.getReturnType(),
+                                methodElement.getEnclosingElement().asType());
+
+                        boolean foundPublicSetter = followsNamePattern && 
checkForAssignable && isPublicMethod;
+                        if (foundPublicSetter) {
+                            // Hurray we found a public setter for the field!
+                            return;
+                        }
+                    }
+                }
+            }
+            // If the setter was not found generate a compiler warning.
+            processingEnv
+                    .getMessager()
+                    .printMessage(
+                            Diagnostic.Kind.ERROR,
+                            String.format(
+                                    "The field `%s` does not have a public 
setter, Note that @SuppressWarnings(\"%s\"), can be used on the field to 
suppress the compilation error. ",
+                                    fieldName, 
SUPPRESS_WARNING_PUBLIC_SETTER_STRING),
+                            element);
+        }
+    }
+
+    /**
+     *  Helper method to get the expected Method name in a field.
+     *  For example if the field name is 'isopen', then the expected setter 
would be 'setOpen' or 'withOpen'
+     *  This method is supposed to return the capitalized 'Open', fieldName 
which is expected in the setter.
+     * @param fieldName who's setter we are checking.
+     * @return The expected fieldName that will come after withxxxx or setxxxx
+     */
+    public static String expectedFieldNameInASetter(String fieldName) {
+        if (fieldName.startsWith("is")) fieldName = fieldName.substring(2);
+
+        if (StringUtils.isEmpty(fieldName)) return ""; // Return empty string 
if the field is a blank String.
+
+        return String.format(
+                "%s%s",
+                fieldName.substring(0, 1).toUpperCase(Locale.ROOT),
+                fieldName.substring(1)); // we do not need to Lowercase here 
examples like field name 'ignoreExceptions'

Review Comment:
   Changed as per suggestion 😄 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to