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 0c3a1ea4fe New BeanCreator API
0c3a1ea4fe is described below

commit 0c3a1ea4febca7a89902fb399b683c31a2054f68
Author: James Bognar <[email protected]>
AuthorDate: Wed Jan 21 11:09:48 2026 -0500

    New BeanCreator API
---
 .../juneau/commons/reflect/AnnotationInfo.java     |  2 +-
 .../apache/juneau/commons/reflect/FieldInfo.java   | 53 +++++++++++-
 .../juneau/commons/reflect/FieldInfo_Test.java     | 95 +++++++++++++++++++++-
 3 files changed, 147 insertions(+), 3 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/AnnotationInfo.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/AnnotationInfo.java
index da01c79b6a..ff43510ff0 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/AnnotationInfo.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/AnnotationInfo.java
@@ -697,7 +697,7 @@ public class AnnotationInfo<T extends Annotation> {
         *
         * @return A new map showing the attributes of this annotation info.
         */
-       protected FluentMap<String,Object> properties() {
+       public FluentMap<String,Object> properties() {
                // @formatter:off
                var ca = info(a.annotationType());
                var ja = mapb().sorted().buildFluent();  // NOAI
diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
index 5c43f8bba3..a6ea07b7b7 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/FieldInfo.java
@@ -131,6 +131,7 @@ public class FieldInfo extends AccessibleInfo implements 
Comparable<FieldInfo>,
        private final Supplier<ClassInfo> type;
        private final Supplier<List<AnnotationInfo<Annotation>>> annotations;  
// All annotations declared directly on this field.
        private final Supplier<String> fullName;  // Fully qualified field name 
(declaring-class.field-name).
+       private final Supplier<String> toString;  // String representation with 
modifiers, type, and full name.
 
        /**
         * Constructor.
@@ -151,6 +152,7 @@ public class FieldInfo extends AccessibleInfo implements 
Comparable<FieldInfo>,
                this.type = mem(() -> ClassInfo.of(inner.getType(), 
inner.getGenericType()));
                this.annotations = mem(() -> 
stream(inner.getAnnotations()).flatMap(a -> 
AnnotationUtils.streamRepeated(a)).map(a -> ai(this, a)).toList());
                this.fullName = mem(this::findFullName);
+               this.toString = mem(this::findToString);
        }
 
        /**
@@ -480,9 +482,58 @@ public class FieldInfo extends AccessibleInfo implements 
Comparable<FieldInfo>,
        // Annotatable interface methods
        
//-----------------------------------------------------------------------------------------------------------------
 
+       /**
+        * Returns a detailed string representation of this field.
+        *
+        * <p>
+        * The returned string includes:
+        * <ul>
+        *      <li>Modifiers (public, private, protected, static, final, 
volatile, transient)
+        *      <li>Field type with generics (e.g., "List&lt;String&gt;")
+        *      <li>Fully qualified field name (declaring-class.field-name)
+        * </ul>
+        *
+        * <h5 class='section'>Examples:</h5>
+        * <p class='bjava'>
+        *      <jc>// Simple field</jc>
+        *      FieldInfo <jv>fi</jv> = ...;
+        *      <jv>fi</jv>.toString();
+        *      <jc>// Returns: "public java.lang.String 
org.example.MyClass.name"</jc>
+        *
+        *      <jc>// Static final field</jc>
+        *      <jc>// Returns: "public static final int 
org.example.MyClass.MAX_VALUE"</jc>
+        *
+        *      <jc>// Generic field</jc>
+        *      <jc>// Returns: "private java.util.List&lt;java.lang.String&gt; 
org.example.MyClass.items"</jc>
+        *
+        *      <jc>// Volatile field</jc>
+        *      <jc>// Returns: "volatile boolean org.example.MyClass.flag"</jc>
+        * </p>
+        *
+        * @return A detailed string representation including modifiers, type, 
and full name.
+        */
        @Override
        public String toString() {
-               return cn(inner.getDeclaringClass()) + "." + inner.getName();
+               return toString.get();
+       }
+
+       private String findToString() {
+               var sb = new StringBuilder(256);
+
+               // Modifiers
+               var mods = Modifier.toString(getModifiers());
+               if (nn(mods) && ! mods.isEmpty()) {
+                       sb.append(mods).append(" ");
+               }
+
+               // Field type (use generic type to show generics)
+               var genericType = inner.getGenericType();
+               ClassInfo.of(genericType).appendNameFormatted(sb, FULL, true, 
'$', BRACKETS);
+
+               // Fully qualified field name
+               sb.append(" ").append(getNameFull());
+
+               return sb.toString();
        }
 
        private String findFullName() {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/FieldInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/FieldInfo_Test.java
index 450f7e773c..378d981b24 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/FieldInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/FieldInfo_Test.java
@@ -670,7 +670,100 @@ class FieldInfo_Test extends TestBase {
        
//====================================================================================================
        @Test
        void a031_toString() {
-               
assertEquals("org.apache.juneau.commons.reflect.FieldInfo_Test$E.a1", 
e_a1.toString());
+               // e_a1 is a public int field, new toString() includes 
modifiers and type
+               assertEquals("public int 
org.apache.juneau.commons.reflect.FieldInfo_Test$E.a1", e_a1.toString());
+       }
+
+       @Test
+       void a032_toString_comprehensive() {
+               var ci = ClassInfo.of(ToStringTestClass.class);
+
+               // Public field
+               var publicField = ci.getPublicField(x -> 
x.hasName("publicField")).get();
+               assertEquals("public int 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.publicField",
 publicField.toString());
+
+               // Private field
+               var privateField = ci.getDeclaredField(x -> 
x.hasName("privateField")).get();
+               assertEquals("private java.lang.String 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.privateField",
 privateField.toString());
+
+               // Protected field
+               var protectedField = ci.getDeclaredField(x -> 
x.hasName("protectedField")).get();
+               assertEquals("protected boolean 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.protectedField",
 protectedField.toString());
+
+               // Package-private field
+               var packageField = ci.getDeclaredField(x -> 
x.hasName("packageField")).get();
+               assertEquals("double 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.packageField",
 packageField.toString());
+
+               // Static field
+               var staticField = ci.getPublicField(x -> 
x.hasName("staticField")).get();
+               assertEquals("public static long 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.staticField",
 staticField.toString());
+
+               // Final field
+               var finalField = ci.getPublicField(x -> 
x.hasName("finalField")).get();
+               assertEquals("public static final int 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.finalField", 
finalField.toString());
+
+               // Volatile field
+               var volatileField = ci.getPublicField(x -> 
x.hasName("volatileField")).get();
+               assertEquals("public volatile boolean 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.volatileField",
 volatileField.toString());
+
+               // Transient field
+               var transientField = ci.getPublicField(x -> 
x.hasName("transientField")).get();
+               assertEquals("public transient java.lang.Object 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.transientField",
 transientField.toString());
+
+               // Generic field (private, so use getDeclaredField)
+               var genericField = ci.getDeclaredField(x -> 
x.hasName("genericField")).get();
+               assertEquals("private java.util.List<java.lang.String> 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.genericField",
 genericField.toString());
+
+               // Generic field with multiple type parameters (private, so use 
getDeclaredField)
+               var mapField = ci.getDeclaredField(x -> 
x.hasName("mapField")).get();
+               assertEquals("private 
java.util.Map<java.lang.String,java.lang.Integer> 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.mapField", 
mapField.toString());
+
+               // Array field
+               var arrayField = ci.getPublicField(x -> 
x.hasName("arrayField")).get();
+               assertEquals("public int[] 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.arrayField", 
arrayField.toString());
+
+               // Multi-dimensional array field
+               var matrixField = ci.getPublicField(x -> 
x.hasName("matrixField")).get();
+               assertEquals("public java.lang.String[][] 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.matrixField",
 matrixField.toString());
+
+               // Generic array field
+               var genericArrayField = ci.getPublicField(x -> 
x.hasName("genericArrayField")).get();
+               assertEquals("public java.util.List<java.lang.String>[] 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.genericArrayField",
 genericArrayField.toString());
+
+               // Primitive types
+               var byteField = ci.getPublicField(x -> 
x.hasName("byteField")).get();
+               assertEquals("public byte 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.byteField", 
byteField.toString());
+
+               var charField = ci.getPublicField(x -> 
x.hasName("charField")).get();
+               assertEquals("public char 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.charField", 
charField.toString());
+
+               var floatField = ci.getPublicField(x -> 
x.hasName("floatField")).get();
+               assertEquals("public float 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.floatField", 
floatField.toString());
+
+               // Multiple modifiers
+               var staticFinalField = ci.getPublicField(x -> 
x.hasName("staticFinalField")).get();
+               assertEquals("public static final java.lang.String 
org.apache.juneau.commons.reflect.FieldInfo_Test$ToStringTestClass.staticFinalField",
 staticFinalField.toString());
+       }
+
+       // Test class for toString() comprehensive tests
+       public static class ToStringTestClass {
+               public int publicField;
+               private String privateField;
+               protected boolean protectedField;
+               double packageField;
+               public static long staticField;
+               public static final int finalField = 42;
+               public volatile boolean volatileField;
+               public transient Object transientField;
+               private java.util.List<String> genericField;
+               private java.util.Map<String, Integer> mapField;
+               public int[] arrayField;
+               public String[][] matrixField;
+               public java.util.List<String>[] genericArrayField;
+               public byte byteField;
+               public char charField;
+               public float floatField;
+               public static final String staticFinalField = "constant";
        }
 
        
//====================================================================================================

Reply via email to