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

commit a49cda267406133e07975fa1d6a0764a0dd3eb91
Author: James Bognar <[email protected]>
AuthorDate: Sun Dec 7 16:54:14 2025 -0500

    Marshall module improvements
---
 .../apache/juneau/commons/utils/ClassUtils.java    | 66 +++++++++++++++++++++
 .../src/main/java/org/apache/juneau/BeanMeta.java  | 68 +---------------------
 2 files changed, 67 insertions(+), 67 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java
index b1f09277b4..b429c3038e 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/ClassUtils.java
@@ -524,6 +524,72 @@ public class ClassUtils {
                return null;
        }
 
+       /**
+        * Recursively determines the classes represented by parameterized 
types in the class hierarchy of the specified
+        * type, and puts the results in the specified map.
+        *
+        * <p>
+        * For example, given the following classes...
+        * <p class='bjava'>
+        *      <jk>public static class</jk> BeanA&lt;T&gt; {
+        *              <jk>public</jk> T <jf>x</jf>;
+        *      }
+        *      <jk>public static class</jk> BeanB <jk>extends</jk> 
BeanA&lt;Integer> {...}
+        * </p>
+        * <p>
+        *      ...calling this method on {@code BeanB.class} will load the 
following data into {@code m} indicating
+        *      that the {@code T} parameter on the BeanA class is implemented 
with an {@code Integer}:
+        * <p class='bcode'>
+        *      {BeanA.class:[Integer.class]}
+        * </p>
+        *
+        * <h5 class='section'>Known Limitations:</h5>
+        * <p>
+        * This code doesn't currently properly handle the following situation 
with nested generic bounds:
+        * <p class='bjava'>
+        *      <jk>public static class</jk> BeanB&lt;T <jk>extends</jk> 
Number&gt; <jk>extends</jk> BeanA&lt;>;
+        *      <jk>public static class</jk> BeanC <jk>extends</jk> 
BeanB&lt;Integer>;
+        * </p>
+        *
+        * <p>
+        * When called on {@code BeanC}, the type variable will be resolved as 
{@code Number}, not {@code Integer}.
+        * This limitation exists because the intermediate type parameter bound 
information is lost during type resolution
+        *
+        * @param t The type we're recursing.
+        * @param m Where the results are loaded.
+        */
+       public static Map<Class<?>,Class<?>[]> findTypeVarImpls(Type t) {
+               Map<Class<?>,Class<?>[]> m = new LinkedHashMap<>();
+               return findTypeVarImpls(t, m);
+       }
+
+       private static Map<Class<?>,Class<?>[]> findTypeVarImpls(Type t, 
Map<Class<?>,Class<?>[]> m) {
+               if (t instanceof Class<?> c) {
+                       findTypeVarImpls(c.getGenericSuperclass(), m);
+                       for (var ci : c.getGenericInterfaces())
+                               findTypeVarImpls(ci, m);
+               } else if (t instanceof ParameterizedType t2) {
+                       var rt = t2.getRawType();
+                       if (rt instanceof Class) {
+                               Type[] gImpls = t2.getActualTypeArguments();
+                               Class<?>[] gTypes = new Class[gImpls.length];
+                               for (var i = 0; i < gImpls.length; i++) {
+                                       Type gt = gImpls[i];
+                                       if (gt instanceof Class<?> c)
+                                               gTypes[i] = c;
+                                       else if (gt instanceof TypeVariable<?> 
tv) {
+                                               for (var upperBound : 
tv.getBounds())
+                                                       if (upperBound 
instanceof Class upperBound2)
+                                                               gTypes[i] = 
upperBound2;
+                                       }
+                               }
+                               m.put((Class<?>)rt, gTypes);
+                               findTypeVarImpls(t2.getRawType(), m);
+                       }
+               }
+               return m;
+       }
+
        private static boolean canAddTo(Class<?> c) {
                var b = MODIFIABLE_COLLECTION_TYPES.get(c);
                if (b == null) {
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index a750243f65..94a7adade4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -150,7 +150,6 @@ public class BeanMeta<T> {
                Map<Method,String> setterProps = map();
                BeanPropertyMeta dynaProperty;
 
-               Map<Class<?>,Class<?>[]> typeVarImpls;
                ConstructorInfo constructor, implClassConstructor;
                String[] constructorArgs = {};
                PropertyNamer propertyNamer;
@@ -398,10 +397,7 @@ public class BeanMeta<T> {
                                        });
                                }
 
-                               typeVarImpls = map();
-                               findTypeVarImpls(c, typeVarImpls);
-                               if (typeVarImpls.isEmpty())
-                                       typeVarImpls = null;
+                               var typeVarImpls = 
ClassUtils.findTypeVarImpls(c);
 
                                // Eliminate invalid properties, and set the 
contents of getterProps and setterProps.
                                for (Iterator<BeanPropertyMeta.Builder> i = 
normalProps.values().iterator(); i.hasNext();) {
@@ -699,65 +695,6 @@ public class BeanMeta<T> {
                return value.get();
        }
 
-       /**
-        * Recursively determines the classes represented by parameterized 
types in the class hierarchy of the specified
-        * type, and puts the results in the specified map.
-        *
-        * <p>
-        * For example, given the following classes...
-        * <p class='bjava'>
-        *      <jk>public static class</jk> BeanA&lt;T&gt; {
-        *              <jk>public</jk> T <jf>x</jf>;
-        *      }
-        *      <jk>public static class</jk> BeanB <jk>extends</jk> 
BeanA&lt;Integer> {...}
-        * </p>
-        * <p>
-        *      ...calling this method on {@code BeanB.class} will load the 
following data into {@code m} indicating
-        *      that the {@code T} parameter on the BeanA class is implemented 
with an {@code Integer}:
-        * <p class='bcode'>
-        *      {BeanA.class:[Integer.class]}
-        * </p>
-        *
-        * <h5 class='section'>Known Limitations:</h5>
-        * <p>
-        * This code doesn't currently properly handle the following situation 
with nested generic bounds:
-        * <p class='bjava'>
-        *      <jk>public static class</jk> BeanB&lt;T <jk>extends</jk> 
Number&gt; <jk>extends</jk> BeanA&lt;>;
-        *      <jk>public static class</jk> BeanC <jk>extends</jk> 
BeanB&lt;Integer>;
-        * </p>
-        *
-        * <p>
-        * When called on {@code BeanC}, the type variable will be resolved as 
{@code Number}, not {@code Integer}.
-        * This limitation exists because the intermediate type parameter bound 
information is lost during type resolution
-        *
-        * @param t The type we're recursing.
-        * @param m Where the results are loaded.
-        */
-       static final void findTypeVarImpls(Type t, Map<Class<?>,Class<?>[]> m) {
-               if (t instanceof Class<?> c) {
-                       findTypeVarImpls(c.getGenericSuperclass(), m);
-                       for (var ci : c.getGenericInterfaces())
-                               findTypeVarImpls(ci, m);
-               } else if (t instanceof ParameterizedType t2) {
-                       var rt = t2.getRawType();
-                       if (rt instanceof Class) {
-                               Type[] gImpls = t2.getActualTypeArguments();
-                               Class<?>[] gTypes = new Class[gImpls.length];
-                               for (var i = 0; i < gImpls.length; i++) {
-                                       Type gt = gImpls[i];
-                                       if (gt instanceof Class<?> c)
-                                               gTypes[i] = c;
-                                       else if (gt instanceof TypeVariable<?> 
tv) {
-                                               for (var upperBound : 
tv.getBounds())
-                                                       if (upperBound 
instanceof Class upperBound2)
-                                                               gTypes[i] = 
upperBound2;
-                                       }
-                               }
-                               m.put((Class<?>)rt, gTypes);
-                               findTypeVarImpls(t2.getRawType(), m);
-                       }
-               }
-       }
 
        /**
         * Finds @Beanp and @Name annotations from parent methods if this 
method overrides a parent.
@@ -836,8 +773,6 @@ public class BeanMeta<T> {
        protected final BeanContext ctx;
        /** Optional bean filter associated with the target class. */
        protected final BeanFilter beanFilter;
-       /** Type variables implemented by this bean. */
-       protected final Map<Class<?>,Class<?>[]> typeVarImpls;
 
        /** The constructor for this bean. */
        protected final ConstructorInfo constructor;
@@ -912,7 +847,6 @@ public class BeanMeta<T> {
                getterProps = u(b.getterProps);
                setterProps = u(b.setterProps);
                dynaProperty = b.dynaProperty;
-               typeVarImpls = u(b.typeVarImpls);
                constructor = b.constructor;
                constructorArgs = b.constructorArgs;
                beanRegistry = b.beanRegistry;

Reply via email to