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

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new a3b9c8f543 Utility class modernization
a3b9c8f543 is described below

commit a3b9c8f543725b82aa1c3b2923af02ef08ec8f5f
Author: James Bognar <[email protected]>
AuthorDate: Tue Nov 4 18:44:05 2025 -0500

    Utility class modernization
---
 .../juneau/common/reflect/AnnotationInfo.java      | 140 ++++++++++++++-
 .../apache/juneau/common/reflect/FieldInfo.java    |   1 -
 .../juneau/common/reflect/ParameterInfo.java       |   4 +-
 .../reflect/AnnotationInfo_ValueMethods_Test.java  | 189 +++++++++++++++++++++
 4 files changed, 328 insertions(+), 6 deletions(-)

diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
index 0b2e046bea..8af5663e01 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationInfo.java
@@ -494,15 +494,149 @@ public class AnnotationInfo<T extends Annotation> {
                        mi.getDeclaredAnnotationInfos().forEach(ai -> 
ai.accept(filter, action));
        }
 
+       /**
+        * Returns <jk>true</jk> if this annotation has the specified simple 
name.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      <jk>boolean</jk> <jv>isName</jv> = 
<jv>annotationInfo</jv>.hasSimpleName(<js>"Name"</js>);
+        * </p>
+        *
+        * @param value The simple name to check.
+        * @return <jk>true</jk> if this annotation has the specified simple 
name.
+        */
        public boolean hasSimpleName(String value) {
                return eq(value, a.annotationType().getSimpleName());
        }
 
-       public String getValue() {
+       /**
+        * Returns <jk>true</jk> if this annotation has the specified 
fully-qualified name.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      <jk>boolean</jk> <jv>isName</jv> = 
<jv>annotationInfo</jv>.hasName(<js>"org.apache.juneau.annotation.Name"</js>);
+        * </p>
+        *
+        * @param value The fully-qualified name to check.
+        * @return <jk>true</jk> if this annotation has the specified 
fully-qualified name.
+        */
+       public boolean hasName(String value) {
+               return eq(value, a.annotationType().getName());
+       }
+
+       /**
+        * Returns the value of the <c>value()</c> method on this annotation as 
a string.
+        *
+        * @return An optional containing the value of the <c>value()</c> 
method, or empty if not found or not a string.
+        */
+       public Optional<String> getValue() {
                return getString("value");
        }
 
-       public String getString(String methodName) {
-               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(String.class)).map(x -> 
s(x.invoke(a))).findFirst().orElse(null);
+       /**
+        * Returns the value of the specified method on this annotation as a 
string.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a string.
+        */
+       public Optional<String> getString(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(String.class)).map(x -> 
s(x.invoke(a))).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as an 
integer.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not an integer.
+        */
+       public Optional<Integer> getInt(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(int.class)).map(x -> 
(Integer)x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
boolean.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a boolean.
+        */
+       public Optional<Boolean> getBoolean(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(boolean.class)).map(x -> 
(Boolean)x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
long.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a long.
+        */
+       public Optional<Long> getLong(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(long.class)).map(x -> 
(Long)x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
double.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a double.
+        */
+       public Optional<Double> getDouble(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(double.class)).map(x -> 
(Double)x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
float.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a float.
+        */
+       public Optional<Float> getFloat(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(float.class)).map(x -> 
(Float)x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
class.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a class.
+        */
+       @SuppressWarnings("unchecked")
+       public Optional<Class<?>> getClassValue(String methodName) {
+               return 
(Optional<Class<?>>)(Optional<?>)methods.get().stream().filter(x -> 
eq(methodName, x.getSimpleName()) && x.hasReturnType(Class.class)).map(x -> 
x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
string array.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a string array.
+        */
+       public Optional<String[]> getStringArray(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName()) && x.hasReturnType(String[].class)).map(x -> 
(String[])x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the value of the specified method on this annotation as a 
class array.
+        *
+        * @param methodName The method name.
+        * @return An optional containing the value of the specified method, or 
empty if not found or not a class array.
+        */
+       @SuppressWarnings("unchecked")
+       public Optional<Class<?>[]> getClassArray(String methodName) {
+               return 
(Optional<Class<?>[]>)(Optional<?>)methods.get().stream().filter(x -> 
eq(methodName, x.getSimpleName()) && x.hasReturnType(Class[].class)).map(x -> 
x.invoke(a)).findFirst();
+       }
+
+       /**
+        * Returns the return type of the specified method on this annotation.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      Optional&lt;ClassInfo&gt; <jv>returnType</jv> = 
<jv>annotationInfo</jv>.getReturnType(<js>"value"</js>);
+        * </p>
+        *
+        * @param methodName The method name.
+        * @return An optional containing the return type of the specified 
method, or empty if method not found.
+        */
+       public Optional<ClassInfo> getReturnType(String methodName) {
+               return methods.get().stream().filter(x -> eq(methodName, 
x.getSimpleName())).map(x -> x.getReturnType()).findFirst();
        }
 }
\ No newline at end of file
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
index 1356dcb912..a67db4fdb1 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/FieldInfo.java
@@ -18,7 +18,6 @@ package org.apache.juneau.common.reflect;
 
 import static org.apache.juneau.common.utils.CollectionUtils.*;
 import static org.apache.juneau.common.utils.PredicateUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
 import static org.apache.juneau.common.utils.Utils.*;
 
 import java.lang.annotation.*;
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
index c34e0610ff..110489cbb6 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ParameterInfo.java
@@ -308,7 +308,7 @@ public class ParameterInfo extends ElementInfo implements 
Annotatable {
                for (var mp : getMatchingParameters()) {
                        for (var ai : mp.getAnnotationInfos()) {
                                if (ai.hasSimpleName("Name")) {
-                                       String value = ai.getValue();
+                                       String value = 
ai.getValue().orElse(null);
                                        if (value != null)
                                                return value;
                                }
@@ -349,7 +349,7 @@ public class ParameterInfo extends ElementInfo implements 
Annotatable {
                for (var mp : getMatchingParameters()) {
                        for (var ai : mp.getAnnotationInfos()) {
                                if (ai.hasSimpleName("Named") || 
ai.hasSimpleName("Qualifier")) {
-                                       String value = ai.getValue();
+                                       String value = 
ai.getValue().orElse(null);
                                        if (value != null)
                                                return value;
                                }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfo_ValueMethods_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfo_ValueMethods_Test.java
new file mode 100644
index 0000000000..0299759dbe
--- /dev/null
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/AnnotationInfo_ValueMethods_Test.java
@@ -0,0 +1,189 @@
+/*
+ * 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.juneau.common.reflect;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.lang.annotation.*;
+
+import org.junit.jupiter.api.*;
+
+/**
+ * Tests for AnnotationInfo value retrieval methods.
+ */
+public class AnnotationInfo_ValueMethods_Test {
+
+       @Target(ElementType.TYPE)
+       @Retention(RetentionPolicy.RUNTIME)
+       public @interface TestAnnotation {
+               String stringValue() default "default";
+               int intValue() default 42;
+               boolean boolValue() default true;
+               long longValue() default 100L;
+               double doubleValue() default 3.14;
+               float floatValue() default 2.5f;
+               Class<?> classValue() default String.class;
+               String[] stringArray() default {"a", "b"};
+               Class<?>[] classArray() default {String.class, Integer.class};
+       }
+
+       @TestAnnotation(
+               stringValue = "test",
+               intValue = 123,
+               boolValue = false,
+               longValue = 999L,
+               doubleValue = 1.23,
+               floatValue = 4.56f,
+               classValue = Integer.class,
+               stringArray = {"x", "y", "z"},
+               classArray = {Long.class, Double.class}
+       )
+       public static class AnnotatedClass {}
+
+       private AnnotationInfo<TestAnnotation> getTestAnnotationInfo() {
+               var ci = ClassInfo.of(AnnotatedClass.class);
+               var annotation = ci.getAnnotation(TestAnnotation.class);
+               return AnnotationInfo.of(ci, annotation);
+       }
+
+       @Test
+       public void testHasName() {
+               var ai = getTestAnnotationInfo();
+               
+               
assertTrue(ai.hasName("org.apache.juneau.common.reflect.AnnotationInfo_ValueMethods_Test$TestAnnotation"));
+               assertFalse(ai.hasName("TestAnnotation"));
+       }
+
+       @Test
+       public void testHasSimpleName() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.hasSimpleName("TestAnnotation"));
+               
assertFalse(ai.hasSimpleName("org.apache.juneau.common.reflect.AnnotationInfo_ValueMethods_Test$TestAnnotation"));
+       }
+
+       @Test
+       public void testGetString() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getString("stringValue").isPresent());
+               assertEquals("test", ai.getString("stringValue").get());
+               assertTrue(ai.getString("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetInt() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getInt("intValue").isPresent());
+               assertEquals(123, ai.getInt("intValue").get());
+               assertTrue(ai.getInt("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetBoolean() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getBoolean("boolValue").isPresent());
+               assertEquals(false, ai.getBoolean("boolValue").get());
+               assertTrue(ai.getBoolean("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetLong() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getLong("longValue").isPresent());
+               assertEquals(999L, ai.getLong("longValue").get());
+               assertTrue(ai.getLong("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetDouble() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getDouble("doubleValue").isPresent());
+               assertEquals(1.23, ai.getDouble("doubleValue").get(), 0.001);
+               assertTrue(ai.getDouble("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetFloat() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getFloat("floatValue").isPresent());
+               assertEquals(4.56f, ai.getFloat("floatValue").get(), 0.001);
+               assertTrue(ai.getFloat("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetClassValue() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getClassValue("classValue").isPresent());
+               assertEquals(Integer.class, 
ai.getClassValue("classValue").get());
+               assertTrue(ai.getClassValue("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetStringArray() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getStringArray("stringArray").isPresent());
+               String[] array = ai.getStringArray("stringArray").get();
+               assertNotNull(array);
+               assertEquals(3, array.length);
+               assertEquals("x", array[0]);
+               assertEquals("y", array[1]);
+               assertEquals("z", array[2]);
+               assertTrue(ai.getStringArray("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetClassArray() {
+               var ai = getTestAnnotationInfo();
+               
+               assertTrue(ai.getClassArray("classArray").isPresent());
+               Class<?>[] array = ai.getClassArray("classArray").get();
+               assertNotNull(array);
+               assertEquals(2, array.length);
+               assertEquals(Long.class, array[0]);
+               assertEquals(Double.class, array[1]);
+               assertTrue(ai.getClassArray("nonexistent").isEmpty());
+       }
+
+       @Test
+       public void testGetReturnType() {
+               var ai = getTestAnnotationInfo();
+               
+               // Test various return types
+               assertTrue(ai.getReturnType("stringValue").isPresent());
+               assertEquals(String.class, 
ai.getReturnType("stringValue").get().inner());
+               assertEquals(int.class, 
ai.getReturnType("intValue").get().inner());
+               assertEquals(boolean.class, 
ai.getReturnType("boolValue").get().inner());
+               assertEquals(long.class, 
ai.getReturnType("longValue").get().inner());
+               assertEquals(double.class, 
ai.getReturnType("doubleValue").get().inner());
+               assertEquals(float.class, 
ai.getReturnType("floatValue").get().inner());
+               assertEquals(Class.class, 
ai.getReturnType("classValue").get().inner());
+               assertEquals(String[].class, 
ai.getReturnType("stringArray").get().inner());
+               assertEquals(Class[].class, 
ai.getReturnType("classArray").get().inner());
+               
+               // Nonexistent method
+               assertTrue(ai.getReturnType("nonexistent").isEmpty());
+       }
+}
+

Reply via email to