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

commit 54dc52948445b6c4590f93dd557eb0c1bedd8583
Author: James Bognar <[email protected]>
AuthorDate: Sun Dec 7 20:15:46 2025 -0500

    Marshall module improvements
---
 .../src/main/java/org/apache/juneau/ClassMeta.java | 105 +++++++++------------
 1 file changed, 43 insertions(+), 62 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index c08c8c4452..d8e6fe8b36 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -137,36 +137,36 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
                return true;
        }
 
-       private final List<ClassMeta<?>> args;                                  
                                        // Arg types if this is an array of 
args.
-       private final BeanContext beanContext;                                  
                                        // The bean context that created this 
object.
+       private final List<ClassMeta<?>> args;                                  
   // Arg types if this is an array of args.
+       private final BeanContext beanContext;                                  
   // The bean context that created this object.
        private final OptionalSupplier<BeanFilter> beanFilter;
-       private final Supplier<BuilderSwap<T,?>> builderSwap;                   
                                        // The builder swap associated with 
this bean (if it has one).
-       private final Categories cat;                                           
                                        // The class category.
-       private final ConcurrentHashMap<Class<?>,ObjectSwap<?,?>> childSwapMap; 
                                        // Maps normal subclasses to 
ObjectSwaps.
-       private final ObjectSwap<?,?>[] childSwaps;                             
                                        // Any ObjectSwaps where the normal 
type is a subclass of this class.
-       private final ConcurrentHashMap<Class<?>,ObjectSwap<?,?>> 
childUnswapMap;                                       // Maps swap subclasses 
to ObjectSwaps.
-       private final Supplier<String> dictionaryName;                          
                                        // The dictionary name of this class if 
it has one.
-       private final ClassMeta<?> elementType;                                 
                                        // If ARRAY or COLLECTION, the element 
class type.
-       private final OptionalSupplier<String> example;                         
                                                // Example JSON.
-       private final OptionalSupplier<FieldInfo> exampleField;                 
                                                // The @Example-annotated field 
(if it has one).
-       private final OptionalSupplier<MethodInfo> exampleMethod;               
                                                // The example() or 
@Example-annotated method (if it has one).
+       private final Supplier<BuilderSwap<T,?>> builderSwap;                   
   // The builder swap associated with this bean (if it has one).
+       private final Categories cat;                                           
   // The class category.
+       private final Cache<Class<?>,ObjectSwap<?,?>> childSwapMap;             
   // Maps normal subclasses to ObjectSwaps.
+       private final List<ObjectSwap<?,?>> childSwaps;                         
   // Any ObjectSwaps where the normal type is a subclass of this class.
+       private final Cache<Class<?>,ObjectSwap<?,?>> childUnswapMap;           
   // Maps swap subclasses to ObjectSwaps.
+       private final Supplier<String> dictionaryName;                          
   // The dictionary name of this class if it has one.
+       private final ClassMeta<?> elementType;                                 
   // If ARRAY or COLLECTION, the element class type.
+       private final OptionalSupplier<String> example;                         
   // Example JSON.
+       private final OptionalSupplier<FieldInfo> exampleField;                 
   // The @Example-annotated field (if it has one).
+       private final OptionalSupplier<MethodInfo> exampleMethod;               
   // The example() or @Example-annotated method (if it has one).
        private final Supplier<BidiMap<Object,String>> enumValues;
        private final Map<Class<?>,Mutater<?,T>> fromMutaters = new 
ConcurrentHashMap<>();
-       private final OptionalSupplier<MethodInfo> fromStringMethod;            
                                                // Static fromString(String) or 
equivalent method
-       private final OptionalSupplier<ClassInfoTyped<? extends T>> implClass;  
                                               // The implementation class to 
use if this is an interface.
-       private final OptionalSupplier<InvocationHandler> 
proxyInvocationHandler;                                                         
     // The invocation handler for this class (if it has one).
-       private final ClassMeta<?> keyType;                                     
                                        // If MAP, the key class type.
+       private final OptionalSupplier<MethodInfo> fromStringMethod;            
   // Static fromString(String) or equivalent method
+       private final OptionalSupplier<ClassInfoTyped<? extends T>> implClass;  
   // The implementation class to use if this is an interface.
+       private final OptionalSupplier<InvocationHandler> 
proxyInvocationHandler;  // The invocation handler for this class (if it has 
one).
+       private final ClassMeta<?> keyType;                                     
   // If MAP, the key class type.
        private final SimpleReadWriteLock lock = new SimpleReadWriteLock(false);
        private final OptionalSupplier<MarshalledFilter> marshalledFilter;
-       private final Supplier<Property<T,Object>> nameProperty;                
                            // The method to set the name on an object (if it 
has one).
-       private final OptionalSupplier<ConstructorInfo> noArgConstructor;       
                                                // The no-arg constructor for 
this class (if it has one).
-       private final Supplier<Property<T,Object>> parentProperty;              
                            // The method to set the parent on an object (if it 
has one).
+       private final Supplier<Property<T,Object>> nameProperty;                
   // The method to set the name on an object (if it has one).
+       private final OptionalSupplier<ConstructorInfo> noArgConstructor;       
   // The no-arg constructor for this class (if it has one).
+       private final Supplier<Property<T,Object>> parentProperty;              
   // The method to set the parent on an object (if it has one).
        private final Map<String,Optional<?>> properties = new 
ConcurrentHashMap<>();
        private final Mutater<String,T> stringMutater;
-       private final OptionalSupplier<ConstructorInfo> stringConstructor;      
                                               // The X(String) constructor (if 
it has one).
-       private final ObjectSwap<T,?>[] swaps;                                  
                                        // The object POJO swaps associated 
with this bean (if it has any).
+       private final OptionalSupplier<ConstructorInfo> stringConstructor;      
   // The X(String) constructor (if it has one).
+       private final ObjectSwap<T,?>[] swaps;                                  
   // The object POJO swaps associated with this bean (if it has any).
        private final Map<Class<?>,Mutater<T,?>> toMutaters = new 
ConcurrentHashMap<>();
-       private final ClassMeta<?> valueType;                                   
                                        // If MAP, the value class type.
+       private final ClassMeta<?> valueType;                                   
   // If MAP, the value class type.
        private final Supplier<Tuple2<BeanMeta<T>,String>> beanMeta;
 
        /**
@@ -194,7 +194,7 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
                this.beanContext = beanContext;
                this.cat = new Categories();
 
-               try (var x = lock.write()) {
+               try (var lw = lock.write()) {
                        // We always immediately add this class meta to the 
bean context cache so that we can resolve recursive references.
                        if (nn(beanContext) && nn(beanContext.cmCache) && 
isCacheable(innerClass))
                                beanContext.cmCache.put(innerClass, this);
@@ -297,7 +297,7 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
                                for (var s : swaps)
                                        _swaps.add(s);
 
-                       ap.find(Swap.class, 
this).stream().map(AnnotationInfo::inner).forEach(x2 -> 
_swaps.add(createSwap(x2)));
+                       ap.find(Swap.class, 
this).stream().map(AnnotationInfo::inner).forEach(x -> 
_swaps.add(createSwap(x)));
                        var ds = DefaultSwaps.find(this);
                        if (ds == null)
                                ds = AutoObjectSwap.find(beanContext, this);
@@ -315,14 +315,27 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
 
                        this.proxyInvocationHandler = 
()->(nn(beanMeta.get().getA()) && beanContext.isUseInterfaceProxies() && 
isInterface()) ? new BeanProxyInvocationHandler<>(beanMeta.get().getA()) : null;
 
-                       this.childSwaps = childSwaps;
-                       this.childUnswapMap = childSwaps == null ? null : new 
ConcurrentHashMap<>();
-                       this.childSwapMap = childSwaps == null ? null : new 
ConcurrentHashMap<>();
+                       this.childSwaps = childSwaps == null ? null : 
Arrays.asList(childSwaps);
+                       this.childUnswapMap = 
Cache.<Class<?>,ObjectSwap<?,?>>create().supplier(x -> findUnswap(x)).build();
+                       this.childSwapMap = 
Cache.<Class<?>,ObjectSwap<?,?>>create().supplier(x -> findSwap(x)).build();
                        this.args = null;
                        this.stringMutater = Mutaters.get(String.class, 
inner());
                }
        }
 
+       protected ObjectSwap<?,?> findSwap(Class<?> c) {
+               if (isEmpty(childSwaps))
+                       return null;
+               return childSwaps.stream().filter(x -> 
x.getNormalClass().isParentOf(c)).findFirst().orElse(null);
+       }
+
+       protected ObjectSwap<?,?> findUnswap(Class<?> c) {
+               if (isEmpty(childSwaps))
+                       return null;
+               return childSwaps.stream().filter(x -> 
x.getSwapClass().isParentOf(c)).findFirst().orElse(null);
+       }
+
+
        /**
         * Constructor for args-arrays.
         */
@@ -1689,23 +1702,7 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
         * @return The resolved {@link ObjectSwap} or <jk>null</jk> if none 
were found.
         */
        protected ObjectSwap<?,?> getChildObjectSwapForSwap(Class<?> 
normalClass) {
-               if (nn(childSwapMap)) {
-                       var s = childSwapMap.get(normalClass);
-                       if (s == null) {
-                               for (var f : childSwaps)
-                                       if (s == null && 
f.getNormalClass().isParentOf(normalClass))
-                                               s = f;
-                               if (s == null)
-                                       s = ObjectSwap.NULL;
-                               var s2 = childSwapMap.putIfAbsent(normalClass, 
s);
-                               if (nn(s2))
-                                       s = s2;
-                       }
-                       if (s == ObjectSwap.NULL)
-                               return null;
-                       return s;
-               }
-               return null;
+               return childSwapMap.get(normalClass);
        }
 
        /**
@@ -1716,23 +1713,7 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
         * @return The resolved {@link ObjectSwap} or <jk>null</jk> if none 
were found.
         */
        protected ObjectSwap<?,?> getChildObjectSwapForUnswap(Class<?> 
swapClass) {
-               if (nn(childUnswapMap)) {
-                       var s = childUnswapMap.get(swapClass);
-                       if (s == null) {
-                               for (var f : childSwaps)
-                                       if (s == null && 
f.getSwapClass().isParentOf(swapClass))
-                                               s = f;
-                               if (s == null)
-                                       s = ObjectSwap.NULL;
-                               var s2 = childUnswapMap.putIfAbsent(swapClass, 
s);
-                               if (nn(s2))
-                                       s = s2;
-                       }
-                       if (s == ObjectSwap.NULL)
-                               return null;
-                       return s;
-               }
-               return null;
+               return childUnswapMap.get(swapClass);
        }
 
        /**
@@ -1745,7 +1726,7 @@ public class ClassMeta<T> extends ClassInfoTyped<T> {
         * @return <jk>true</jk> if this class or any child classes has a 
{@link ObjectSwap} associated with it.
         */
        protected boolean hasChildSwaps() {
-               return nn(childSwaps);
+               return childSwaps != null && ! childSwaps.isEmpty();
        }
 
        /**

Reply via email to