ppkarwasz commented on code in PR #359:
URL: https://github.com/apache/commons-beanutils/pull/359#discussion_r2253733612


##########
src/main/java/org/apache/commons/beanutils2/MethodUtils.java:
##########
@@ -1127,7 +1126,7 @@ private static void setMethodAccessible(final Method 
method) {
             if (!loggedAccessibleWarning) {
                 boolean vulnerableJVM = false;
                 try {
-                    final String specVersion = 
SystemProperties.getJavaSpecificationVersion();
+                    final String specVersion = 
System.getProperty("java.specification.version");

Review Comment:
   The `try…catch` is dead code: Commons BeanUtils has a baseline of Java 8, so 
the Java version will never be lower than 4.



##########
src/main/java/org/apache/commons/beanutils2/FluentPropertyBeanIntrospector.java:
##########
@@ -159,6 +159,6 @@ public void introspect(final IntrospectionContext icontext) 
throws Introspection
      */
     private String propertyName(final Method m) {
         final String methodName = 
m.getName().substring(getWriteMethodPrefix().length());
-        return methodName.length() > 1 ? Introspector.decapitalize(methodName) 
: StringUtils.toRootLowerCase(methodName);
+        return methodName.length() > 1 ? Introspector.decapitalize(methodName) 
: methodName.toLowerCase(Locale.ROOT);

Review Comment:
   ```suggestion
           return Introspector.decapitalize(methodName);
   ```
   
   `Introspector.decapitalize()` actually also handles empty or single 
character names.



##########
src/main/java/org/apache/commons/beanutils2/converters/AbstractConverter.java:
##########
@@ -66,7 +66,7 @@ public abstract class AbstractConverter<D> implements 
Converter<D> {
      * @return the given string trimmed and converter to lower-case.
      */
     protected static String toLowerCase(final Object value) {
-        return StringUtils.toRootLowerCase(toString(value));
+        return toString(value).toLowerCase(Locale.ROOT);

Review Comment:
   In Commons BeanUtils, `AbstractConverter.toLowerCase()` seems to be used as 
a performance optimization: it lowercases the input string once, allowing 
comparisons to use `String.equals()` instead of `String.equalsIgnoreCase()`, 
which involves more complex case folding.
   
   For example, in `BooleanConverter`, this lowercasing is used to perform 
case-insensitive comparisons between the input and user-defined lists of `true` 
values (e.g., *Evet*, *Doğru* in Turkish) and `false` values (e.g., *Hayır*, 
*Yanlış*). When using the default constructor, the converter compares against 
English words like `true`, `yes`, `false`, and `no`, so using `Locale.ROOT` is 
appropriate.
   
   However, this may not be sufficient for converters initialized with 
locale-specific values. For instance, the Turkish word `HAYIR` ("no") would be 
incorrectly lowercased to `hayir` rather than the correct `hayır` when using 
`Locale.ROOT`.
   
   Would it make sense to make the `Locale` configurable in `AbstractConverter` 
(perhaps as a JavaBeans property), with a default of `Locale.ROOT`? This would 
preserve the current behavior while allowing users to specify a locale when 
needed.
   
   **Note**: The case folding algorithm defined in the [Unicode 
standard](https://www.unicode.org/versions/Unicode16.0.0/core-spec/chapter-3/#G53253)
 and used by `String.equalsIgnoreCase()` does not uniformly lowercase all 
characters (e.g., Cherokee characters are uppercased). If the performance 
impact is negligible, it might be worth reconsidering whether 
`BooleanConverter` should use `equalsIgnoreCase()` directly for correctness 
across locales.
   



-- 
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: issues-unsubscr...@commons.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to