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 ef223e7dd0 Marshall module improvements
ef223e7dd0 is described below

commit ef223e7dd09b7c9f3fc1f6b5f34f6de54d6c7e7a
Author: James Bognar <[email protected]>
AuthorDate: Wed Dec 10 13:24:05 2025 -0500

    Marshall module improvements
---
 .../juneau/commons/reflect/ConstructorInfo.java    | 42 +++++++++++++++
 .../apache/juneau/commons/reflect/FieldInfo.java   | 42 +++++++++++++++
 .../apache/juneau/commons/reflect/MethodInfo.java  | 42 +++++++++++++++
 .../juneau/commons/reflect/ParameterInfo.java      | 42 +++++++++++++++
 .../commons/reflect/ConstructorInfo_Test.java      | 59 +++++++++++++++++++++
 .../juneau/commons/reflect/FieldInfo_Test.java     | 60 ++++++++++++++++++++++
 .../juneau/commons/reflect/MethodInfo_Test.java    | 59 +++++++++++++++++++++
 .../juneau/commons/reflect/ParameterInfo_Test.java | 60 ++++++++++++++++++++++
 8 files changed, 406 insertions(+)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
index 8d33dc0c24..20730cb035 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ConstructorInfo.java
@@ -176,6 +176,48 @@ public class ConstructorInfo extends ExecutableInfo 
implements Comparable<Constr
                return (Constructor<T>)inner;
        }
 
+       /**
+        * Compares this ConstructorInfo with the specified object for equality.
+        *
+        * <p>
+        * Two ConstructorInfo objects are considered equal if they wrap the 
same underlying {@link Constructor} object.
+        * This delegates to the underlying {@link Constructor#equals(Object)} 
method.
+        *
+        * <p>
+        * This method makes ConstructorInfo suitable for use as keys in 
hash-based collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @param obj The object to compare with.
+        * @return <jk>true</jk> if the objects are equal, <jk>false</jk> 
otherwise.
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (obj instanceof ConstructorInfo other)
+                       return inner.equals(other.inner);
+               return false;
+       }
+
+       /**
+        * Returns a hash code value for this ConstructorInfo.
+        *
+        * <p>
+        * This delegates to the underlying {@link Constructor#hashCode()} 
method.
+        *
+        * <p>
+        * This method makes ConstructorInfo suitable for use as keys in 
hash-based collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @return A hash code value for this ConstructorInfo.
+        */
+       @Override
+       public int hashCode() {
+               return inner.hashCode();
+       }
+
        /**
         * Shortcut for calling the new-instance method on the underlying 
constructor.
         *
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 a8c25dada6..8cbd6523ed 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
@@ -298,6 +298,48 @@ public class FieldInfo extends AccessibleInfo implements 
Comparable<FieldInfo>,
                return inner;
        }
 
+       /**
+        * Compares this FieldInfo with the specified object for equality.
+        *
+        * <p>
+        * Two FieldInfo objects are considered equal if they wrap the same 
underlying {@link Field} object.
+        * This delegates to the underlying {@link Field#equals(Object)} method.
+        *
+        * <p>
+        * This method makes FieldInfo suitable for use as keys in hash-based 
collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @param obj The object to compare with.
+        * @return <jk>true</jk> if the objects are equal, <jk>false</jk> 
otherwise.
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (obj instanceof FieldInfo other)
+                       return inner.equals(other.inner);
+               return false;
+       }
+
+       /**
+        * Returns a hash code value for this FieldInfo.
+        *
+        * <p>
+        * This delegates to the underlying {@link Field#hashCode()} method.
+        *
+        * <p>
+        * This method makes FieldInfo suitable for use as keys in hash-based 
collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @return A hash code value for this FieldInfo.
+        */
+       @Override
+       public int hashCode() {
+               return inner.hashCode();
+       }
+
        /**
         * Returns <jk>true</jk> if all specified flags are applicable to this 
field.
         *
diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
index 6dc8fdeee2..36b9bd67d9 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/MethodInfo.java
@@ -541,6 +541,48 @@ public class MethodInfo extends ExecutableInfo implements 
Comparable<MethodInfo>
                return inner;
        }
 
+       /**
+        * Compares this MethodInfo with the specified object for equality.
+        *
+        * <p>
+        * Two MethodInfo objects are considered equal if they wrap the same 
underlying {@link Method} object.
+        * This delegates to the underlying {@link Method#equals(Object)} 
method.
+        *
+        * <p>
+        * This method makes MethodInfo suitable for use as keys in hash-based 
collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @param obj The object to compare with.
+        * @return <jk>true</jk> if the objects are equal, <jk>false</jk> 
otherwise.
+        */
+//     @Override
+//     public boolean equals(Object obj) {
+//             if (this == obj)
+//                     return true;
+//             if (obj == null)
+//                     return false;
+//             if (obj instanceof MethodInfo other)
+//                     return inner.equals(other.inner);
+//             return false;
+//     }
+
+       /**
+        * Returns a hash code value for this MethodInfo.
+        *
+        * <p>
+        * This delegates to the underlying {@link Method#hashCode()} method.
+        *
+        * <p>
+        * This method makes MethodInfo suitable for use as keys in hash-based 
collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @return A hash code value for this MethodInfo.
+        */
+       @Override
+       public int hashCode() {
+               return inner.hashCode();
+       }
+
        /**
         * Shortcut for calling the invoke method on the underlying method.
         *
diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ParameterInfo.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ParameterInfo.java
index 8e22c8f14f..486d92b608 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ParameterInfo.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/reflect/ParameterInfo.java
@@ -459,6 +459,48 @@ public class ParameterInfo extends ElementInfo implements 
Annotatable {
                return inner;
        }
 
+       /**
+        * Compares this ParameterInfo with the specified object for equality.
+        *
+        * <p>
+        * Two ParameterInfo objects are considered equal if they wrap the same 
underlying {@link Parameter} object.
+        * This delegates to the underlying {@link Parameter#equals(Object)} 
method.
+        *
+        * <p>
+        * This method makes ParameterInfo suitable for use as keys in 
hash-based collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @param obj The object to compare with.
+        * @return <jk>true</jk> if the objects are equal, <jk>false</jk> 
otherwise.
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj)
+                       return true;
+               if (obj == null)
+                       return false;
+               if (obj instanceof ParameterInfo other)
+                       return inner.equals(other.inner);
+               return false;
+       }
+
+       /**
+        * Returns a hash code value for this ParameterInfo.
+        *
+        * <p>
+        * This delegates to the underlying {@link Parameter#hashCode()} method.
+        *
+        * <p>
+        * This method makes ParameterInfo suitable for use as keys in 
hash-based collections such as {@link HashMap}
+        * and {@link HashSet}.
+        *
+        * @return A hash code value for this ParameterInfo.
+        */
+       @Override
+       public int hashCode() {
+               return inner.hashCode();
+       }
+
        @Override
        public boolean is(ElementFlag flag) {
                return switch (flag) {
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ConstructorInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ConstructorInfo_Test.java
index 6fc80709e1..358d473e56 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ConstructorInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ConstructorInfo_Test.java
@@ -117,6 +117,11 @@ class ConstructorInfo_Test extends TestBase {
                public ExceptionClass() throws Exception {}
        }
 
+       public static class EqualsTestClass {
+               public EqualsTestClass() {}
+               public EqualsTestClass(String param) {}
+       }
+
        
//====================================================================================================
        // accessible()
        
//====================================================================================================
@@ -715,5 +720,59 @@ class ConstructorInfo_Test extends TestBase {
                check("B()", b_c1.toString());
                check("B(String)", b_c2.toString());
        }
+
+       
//====================================================================================================
+       // equals(Object) and hashCode()
+       
//====================================================================================================
+       @Test
+       void a054_equals_hashCode() throws Exception {
+               // Get ConstructorInfo instances from the same Constructor
+               Constructor<?> c1 = EqualsTestClass.class.getConstructor();
+               ConstructorInfo ci1a = ConstructorInfo.of(c1);
+               ConstructorInfo ci1b = ConstructorInfo.of(c1);
+               
+               Constructor<?> c2 = 
EqualsTestClass.class.getConstructor(String.class);
+               ConstructorInfo ci2 = ConstructorInfo.of(c2);
+
+               // Same constructor should be equal
+               assertEquals(ci1a, ci1b);
+               assertEquals(ci1a.hashCode(), ci1b.hashCode());
+               
+               // Different constructors should not be equal
+               assertNotEquals(ci1a, ci2);
+               assertNotEquals(ci1a, null);
+               assertNotEquals(ci1a, "not a ConstructorInfo");
+               
+               // Reflexive
+               assertEquals(ci1a, ci1a);
+               
+               // Symmetric
+               assertEquals(ci1a, ci1b);
+               assertEquals(ci1b, ci1a);
+               
+               // Transitive
+               ConstructorInfo ci1c = ConstructorInfo.of(c1);
+               assertEquals(ci1a, ci1b);
+               assertEquals(ci1b, ci1c);
+               assertEquals(ci1a, ci1c);
+               
+               // HashMap usage - same constructor should map to same value
+               Map<ConstructorInfo, String> map = new HashMap<>();
+               map.put(ci1a, "value1");
+               assertEquals("value1", map.get(ci1b));
+               assertEquals("value1", map.get(ci1c));
+               
+               // HashMap usage - different constructors should map to 
different values
+               map.put(ci2, "value2");
+               assertEquals("value2", map.get(ci2));
+               assertNotEquals("value2", map.get(ci1a));
+               
+               // HashSet usage
+               Set<ConstructorInfo> set = new HashSet<>();
+               set.add(ci1a);
+               assertTrue(set.contains(ci1b));
+               assertTrue(set.contains(ci1c));
+               assertFalse(set.contains(ci2));
+       }
 }
 
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 2075afb3b9..c1334ee39e 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
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
+import java.util.*;
 import java.util.function.*;
 
 import org.apache.juneau.*;
@@ -194,6 +195,11 @@ class FieldInfo_Test extends TestBase {
                testEnum_value1 = testEnum.getPublicField(x -> 
x.hasName("VALUE1")).get(),
                testEnum_value2 = testEnum.getPublicField(x -> 
x.hasName("VALUE2")).get();
 
+       public static class EqualsTestClass {
+               public String field1;
+               public int field2;
+       }
+
        
//====================================================================================================
        // accessible()
        
//====================================================================================================
@@ -666,5 +672,59 @@ class FieldInfo_Test extends TestBase {
        void a031_toString() {
                
assertEquals("org.apache.juneau.commons.reflect.FieldInfo_Test$E.a1", 
e_a1.toString());
        }
+
+       
//====================================================================================================
+       // equals(Object) and hashCode()
+       
//====================================================================================================
+       @Test
+       void a032_equals_hashCode() throws Exception {
+               // Get FieldInfo instances from the same Field
+               Field f1 = EqualsTestClass.class.getField("field1");
+               FieldInfo fi1a = FieldInfo.of(f1);
+               FieldInfo fi1b = FieldInfo.of(f1);
+               
+               Field f2 = EqualsTestClass.class.getField("field2");
+               FieldInfo fi2 = FieldInfo.of(f2);
+
+               // Same field should be equal
+               assertEquals(fi1a, fi1b);
+               assertEquals(fi1a.hashCode(), fi1b.hashCode());
+               
+               // Different fields should not be equal
+               assertNotEquals(fi1a, fi2);
+               assertNotEquals(fi1a, null);
+               assertNotEquals(fi1a, "not a FieldInfo");
+               
+               // Reflexive
+               assertEquals(fi1a, fi1a);
+               
+               // Symmetric
+               assertEquals(fi1a, fi1b);
+               assertEquals(fi1b, fi1a);
+               
+               // Transitive
+               FieldInfo fi1c = FieldInfo.of(f1);
+               assertEquals(fi1a, fi1b);
+               assertEquals(fi1b, fi1c);
+               assertEquals(fi1a, fi1c);
+               
+               // HashMap usage - same field should map to same value
+               Map<FieldInfo, String> map = new HashMap<>();
+               map.put(fi1a, "value1");
+               assertEquals("value1", map.get(fi1b));
+               assertEquals("value1", map.get(fi1c));
+               
+               // HashMap usage - different fields should map to different 
values
+               map.put(fi2, "value2");
+               assertEquals("value2", map.get(fi2));
+               assertNotEquals("value2", map.get(fi1a));
+               
+               // HashSet usage
+               Set<FieldInfo> set = new HashSet<>();
+               set.add(fi1a);
+               assertTrue(set.contains(fi1b));
+               assertTrue(set.contains(fi1c));
+               assertFalse(set.contains(fi2));
+       }
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/MethodInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/MethodInfo_Test.java
index b327d1f13a..07eb0f5588 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/MethodInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/MethodInfo_Test.java
@@ -97,6 +97,11 @@ class MethodInfo_Test extends TestBase {
        }
        static MethodInfo a_m = ofm(A1.class, "m");  // NOSONAR
 
+       public static class EqualsTestClass {
+               public void method1() {}
+               public void method2(String param) {}
+       }
+
        public interface B1 {
                int foo(int x);
                int foo(String x);
@@ -738,5 +743,59 @@ class MethodInfo_Test extends TestBase {
                assertFalse(a_m.isConstructor());
                assertTrue(ClassInfo.of(A1.class).getPublicConstructor(cons -> 
cons.getParameterCount() == 0).get().isConstructor());
        }
+
+       
//====================================================================================================
+       // equals(Object) and hashCode()
+       
//====================================================================================================
+       @Test
+       void a041_equals_hashCode() throws Exception {
+               // Get MethodInfo instances from the same Method
+               Method m1 = EqualsTestClass.class.getMethod("method1");
+               MethodInfo mi1a = MethodInfo.of(m1);
+               MethodInfo mi1b = MethodInfo.of(m1);
+               
+               Method m2 = EqualsTestClass.class.getMethod("method2", 
String.class);
+               MethodInfo mi2 = MethodInfo.of(m2);
+
+               // Same method should be equal
+               assertEquals(mi1a, mi1b);
+               assertEquals(mi1a.hashCode(), mi1b.hashCode());
+               
+               // Different methods should not be equal
+               assertNotEquals(mi1a, mi2);
+               assertNotEquals(mi1a, null);
+               assertNotEquals(mi1a, "not a MethodInfo");
+               
+               // Reflexive
+               assertEquals(mi1a, mi1a);
+               
+               // Symmetric
+               assertEquals(mi1a, mi1b);
+               assertEquals(mi1b, mi1a);
+               
+               // Transitive
+               MethodInfo mi1c = MethodInfo.of(m1);
+               assertEquals(mi1a, mi1b);
+               assertEquals(mi1b, mi1c);
+               assertEquals(mi1a, mi1c);
+               
+               // HashMap usage - same method should map to same value
+               Map<MethodInfo, String> map = new HashMap<>();
+               map.put(mi1a, "value1");
+               assertEquals("value1", map.get(mi1b));
+               assertEquals("value1", map.get(mi1c));
+               
+               // HashMap usage - different methods should map to different 
values
+               map.put(mi2, "value2");
+               assertEquals("value2", map.get(mi2));
+               assertNotEquals("value2", map.get(mi1a));
+               
+               // HashSet usage
+               Set<MethodInfo> set = new HashSet<>();
+               set.add(mi1a);
+               assertTrue(set.contains(mi1b));
+               assertTrue(set.contains(mi1c));
+               assertFalse(set.contains(mi2));
+       }
 }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ParameterInfo_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ParameterInfo_Test.java
index 61bb047168..0093fa6e1d 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ParameterInfo_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/commons/reflect/ParameterInfo_Test.java
@@ -23,6 +23,7 @@ import static org.apache.juneau.commons.utils.Utils.*;
 import static org.junit.jupiter.api.Assertions.*;
 
 import java.lang.annotation.*;
+import java.lang.reflect.*;
 import java.util.*;
 import java.util.function.*;
 import java.util.stream.*;
@@ -246,6 +247,10 @@ class ParameterInfo_Test extends TestBase {
        }
 
        // Constructor hierarchy tests
+       public static class EqualsTestClass {
+               public void method(String param1, int param2) {}
+       }
+
        public static class PC1 {
                public PC1(String foo) {}  // NOSONAR
        }
@@ -859,5 +864,60 @@ class ParameterInfo_Test extends TestBase {
        void a029_toString() {
                assertEquals("a1[1]", e_a1_b.toString());
        }
+
+       
//====================================================================================================
+       // equals(Object) and hashCode()
+       
//====================================================================================================
+       @Test
+       void a030_equals_hashCode() throws Exception {
+               // Get ParameterInfo instances from the same Parameter
+               Method method = EqualsTestClass.class.getMethod("method", 
String.class, int.class);
+               Parameter p1 = method.getParameters()[0];
+               ParameterInfo pi1a = ParameterInfo.of(p1);
+               ParameterInfo pi1b = ParameterInfo.of(p1);
+               
+               Parameter p2 = method.getParameters()[1];
+               ParameterInfo pi2 = ParameterInfo.of(p2);
+
+               // Same parameter should be equal
+               assertEquals(pi1a, pi1b);
+               assertEquals(pi1a.hashCode(), pi1b.hashCode());
+               
+               // Different parameters should not be equal
+               assertNotEquals(pi1a, pi2);
+               assertNotEquals(pi1a, null);
+               assertNotEquals(pi1a, "not a ParameterInfo");
+               
+               // Reflexive
+               assertEquals(pi1a, pi1a);
+               
+               // Symmetric
+               assertEquals(pi1a, pi1b);
+               assertEquals(pi1b, pi1a);
+               
+               // Transitive
+               ParameterInfo pi1c = ParameterInfo.of(p1);
+               assertEquals(pi1a, pi1b);
+               assertEquals(pi1b, pi1c);
+               assertEquals(pi1a, pi1c);
+               
+               // HashMap usage - same parameter should map to same value
+               Map<ParameterInfo, String> map = new HashMap<>();
+               map.put(pi1a, "value1");
+               assertEquals("value1", map.get(pi1b));
+               assertEquals("value1", map.get(pi1c));
+               
+               // HashMap usage - different parameters should map to different 
values
+               map.put(pi2, "value2");
+               assertEquals("value2", map.get(pi2));
+               assertNotEquals("value2", map.get(pi1a));
+               
+               // HashSet usage
+               Set<ParameterInfo> set = new HashSet<>();
+               set.add(pi1a);
+               assertTrue(set.contains(pi1b));
+               assertTrue(set.contains(pi1c));
+               assertFalse(set.contains(pi2));
+       }
 }
 

Reply via email to