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 2d1cde77f1 Utility class modernization
2d1cde77f1 is described below

commit 2d1cde77f191524eaf7cb9aebf9a8c74acde11e8
Author: James Bognar <[email protected]>
AuthorDate: Wed Nov 5 11:49:56 2025 -0500

    Utility class modernization
---
 .../apache/juneau/common/collections/Cache.java    | 112 ++++++++++++++++++---
 .../apache/juneau/common/collections/Cache2.java   |  63 ++++++++++--
 .../apache/juneau/common/collections/Cache3.java   |  55 ++++++++--
 .../apache/juneau/common/collections/Cache4.java   |  56 +++++++++--
 .../apache/juneau/common/collections/Cache5.java   |  57 +++++++++--
 .../juneau/common/reflect/AnnotationProvider.java  |  12 +--
 .../juneau/common/reflect/AnnotationProvider2.java |  19 ++--
 .../juneau/common/reflect/ParameterInfo.java       |   8 +-
 .../juneau/common/utils/MimeTypeDetector.java      |   2 +-
 9 files changed, 309 insertions(+), 75 deletions(-)

diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
index 223f91590e..e287b902ab 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache.java
@@ -100,16 +100,22 @@ import java.util.function.*;
  *
  * <h5 class='section'>Examples:</h5>
  * <p class='bjava'>
- *     <jc>// Simple cache with defaults</jc>
+ *     <jc>// Simple cache with defaults using of()</jc>
  *     Cache&lt;String,Integer&gt; <jv>cache</jv> = 
Cache.<jsm>of</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>).build();
  *
- *     <jc>// Cache with custom configuration</jc>
+ *     <jc>// Cache with custom configuration using of()</jc>
  *     Cache&lt;Class&lt;?&gt;,ClassMeta&gt; <jv>classMetaCache</jv> = Cache
  *             .<jsm>of</jsm>(Class.<jk>class</jk>, ClassMeta.<jk>class</jk>)
  *             .maxSize(500)
- *             .logOnExit()
+ *             .logOnExit(<js>"ClassMeta"</js>)
  *             .build();
  *
+ *     <jc>// Complex generics using create()</jc>
+ *     
Cache&lt;Class&lt;?&gt;,List&lt;AnnotationInfo&lt;Annotation&gt;&gt;&gt; 
<jv>annotationsCache</jv> =
+ *             
Cache.&lt;Class&lt;?&gt;,List&lt;AnnotationInfo&lt;Annotation&gt;&gt;&gt;<jsm>create</jsm>()
+ *                     .supplier(<jk>this</jk>::findClassAnnotations)
+ *                     .build();
+ *
  *     <jc>// Disabled cache for testing</jc>
  *     Cache&lt;String,Object&gt; <jv>disabledCache</jv> = Cache
  *             .<jsm>of</jsm>(String.<jk>class</jk>, Object.<jk>class</jk>)
@@ -134,32 +140,41 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bjava'>
-        *      Cache&lt;String,Pattern&gt; <jv>cache</jv> = Cache
+        *      <jc>// Using of() for simple types</jc>
+        *      Cache&lt;String,Pattern&gt; <jv>cache1</jv> = Cache
         *              .<jsm>of</jsm>(String.<jk>class</jk>, 
Pattern.<jk>class</jk>)
         *              .maxSize(200)
-        *              .logOnExit()
+        *              .logOnExit(<js>"Pattern"</js>)
         *              .build();
+        *
+        *      <jc>// Using create() for complex generics</jc>
+        *      Cache&lt;Class&lt;?&gt;,List&lt;Method&gt;&gt; <jv>cache2</jv> =
+        *              
Cache.&lt;Class&lt;?&gt;,List&lt;Method&gt;&gt;<jsm>create</jsm>()
+        *                      .supplier(<jk>this</jk>::findMethods)
+        *                      .build();
         * </p>
         *
         * <h5 class='section'>See Also:</h5>
         * <ul>
         *      <li class='jm'>{@link Cache#of(Class, Class)}
+        *      <li class='jm'>{@link Cache#create()}
         * </ul>
         *
         * @param <K> The key type.
         * @param <V> The value type.
         */
        public static class Builder<K,V> {
-               boolean disableCaching, logOnExit;
+               boolean disableCaching;
                int maxSize;
-               Class<V> type;
+               String id;
+               boolean logOnExit;
                Function<K,V> supplier;
 
-               Builder(Class<V> type) {
-                       this.type = type;
+               Builder() {
                        disableCaching = env("juneau.cache.disable", false);
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
+                       id = "Cache";
                }
 
                /**
@@ -193,6 +208,32 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
                        return this;
                }
 
+               /**
+                * Conditionally disables or enables caching.
+                *
+                * <p>
+                * When disabled, the {@link Cache#get(Object)} and {@link 
Cache#get(Object, Supplier)} methods
+                * will always invoke the supplier and never store or retrieve 
values from the cache.
+                *
+                * <p>
+                * This is typically used when the disable flag comes from an 
external configuration or system property.
+                *
+                * <h5 class='section'>Example:</h5>
+                * <p class='bjava'>
+                *      Cache&lt;String,Object&gt; <jv>cache</jv> = 
Cache.<jsm>of</jsm>(String.<jk>class</jk>, Object.<jk>class</jk>)
+                *              
.disableCaching(Boolean.<jsm>getBoolean</jsm>(<js>"myapp.disableCache"</js>))
+                *              .build();
+                * </p>
+                *
+                * @param value If <jk>true</jk>, caching is disabled. If 
<jk>false</jk>, caching is enabled (default).
+                * @return This object for method chaining.
+                * @see #disableCaching()
+                */
+               public Builder<K,V> disableCaching(boolean value) {
+                       disableCaching = value;
+                       return this;
+               }
+
                /**
                 * Enables logging of cache statistics when the JVM exits.
                 *
@@ -214,10 +255,29 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
                 *      <li>Monitoring cache efficiency in production
                 * </ul>
                 *
+                * @param id The identifier to use in the log message.
+                * @return This object for method chaining.
+                */
+               public Builder<K,V> logOnExit(String id) {
+                       this.id = id;
+                       this.logOnExit = true;
+                       return this;
+               }
+
+               /**
+                * Conditionally enables logging of cache statistics when the 
JVM exits.
+                *
+                * <p>
+                * When enabled, the cache will register a shutdown hook that 
logs the cache name,
+                * total cache hits, and total cache misses (size of cache) to 
help analyze cache effectiveness.
+                *
+                * @param value Whether to enable logging on exit.
+                * @param id The identifier to use in the log message.
                 * @return This object for method chaining.
                 */
-               public Builder<K,V> logOnExit() {
-                       logOnExit = true;
+               public Builder<K,V> logOnExit(boolean value, String id) {
+                       this.id = id;
+                       this.logOnExit = value;
                        return this;
                }
 
@@ -273,6 +333,30 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
                }
        }
 
+       /**
+        * Creates a new {@link Builder} for constructing a cache with explicit 
type parameters.
+        *
+        * <p>
+        * This variant allows you to specify the cache's generic types 
explicitly without passing
+        * the class objects, which is useful when working with complex 
parameterized types.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      <jc>// Working with complex generic types</jc>
+        *      
Cache&lt;Class&lt;?&gt;,List&lt;AnnotationInfo&lt;Annotation&gt;&gt;&gt; 
<jv>cache</jv> =
+        *              
Cache.&lt;Class&lt;?&gt;,List&lt;AnnotationInfo&lt;Annotation&gt;&gt;&gt;<jsm>create</jsm>()
+        *                      .supplier(<jv>key</jv> -&gt; 
findAnnotations(<jv>key</jv>))
+        *                      .build();
+        * </p>
+        *
+        * @param <K> The key type.
+        * @param <V> The value type.
+        * @return A new builder for configuring the cache.
+        */
+       public static <K,V> Builder<K,V> create() {
+               return new Builder<>();
+       }
+
        /**
         * Creates a new {@link Builder} for constructing a cache.
         *
@@ -287,11 +371,11 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
         * @param <K> The key type.
         * @param <V> The value type.
         * @param key The key type class (used for type safety).
-        * @param type The value type class (used for logging and type safety).
+        * @param type The value type class.
         * @return A new builder for configuring the cache.
         */
        public static <K,V> Builder<K,V> of(Class<K> key, Class<V> type) {
-               return new Builder<>(type);
+               return new Builder<>();
        }
 
        private final int maxSize;
@@ -309,7 +393,7 @@ public class Cache<K,V> extends ConcurrentHashMap<K,V> {
                this.disableCaching = builder.disableCaching;
                this.supplier = builder.supplier != null ? builder.supplier : 
(K)->null;
                if (builder.logOnExit) {
-                       shutdownMessage(() -> scn(builder.type) + " cache:  
hits=" + cacheHits.get() + ", misses: " + size());
+                       shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
index 555f31fdcf..e1f2db4d81 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache2.java
@@ -157,16 +157,17 @@ public class Cache2<K1,K2,V> extends 
ConcurrentHashMap2Key<K1,K2,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,V> {
-               boolean disableCaching, logOnExit;
+               boolean disableCaching;
                int maxSize;
-               Class<V> type;
+               String id;
+               boolean logOnExit;
                Function2<K1,K2,V> supplier;
 
-               Builder(Class<V> type) {
-                       this.type = type;
+               Builder() {
                        disableCaching = env("juneau.cache.disable", false);
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
+                       id = "Cache2";
                }
 
                /**
@@ -247,10 +248,29 @@ public class Cache2<K1,K2,V> extends 
ConcurrentHashMap2Key<K1,K2,V> {
                 *      <li>Monitoring cache efficiency in production
                 * </ul>
                 *
+                * @param id The identifier to use in the log message.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,V> logOnExit() {
-                       logOnExit = true;
+               public Builder<K1,K2,V> logOnExit(String id) {
+                       this.id = id;
+                       this.logOnExit = true;
+                       return this;
+               }
+
+               /**
+                * Conditionally enables logging of cache statistics when the 
JVM exits.
+                *
+                * <p>
+                * When enabled, the cache will register a shutdown hook that 
logs the cache name,
+                * total cache hits, and total cache misses (size of cache) to 
help analyze cache effectiveness.
+                *
+                * @param value Whether to enable logging on exit.
+                * @param id The identifier to use in the log message.
+                * @return This object for method chaining.
+                */
+               public Builder<K1,K2,V> logOnExit(boolean value, String id) {
+                       this.id = id;
+                       this.logOnExit = value;
                        return this;
                }
 
@@ -308,6 +328,31 @@ public class Cache2<K1,K2,V> extends 
ConcurrentHashMap2Key<K1,K2,V> {
 
        }
 
+       /**
+        * Creates a new {@link Builder} for constructing a cache with explicit 
type parameters.
+        *
+        * <p>
+        * This variant allows you to specify the cache's generic types 
explicitly without passing
+        * the class objects, which is useful when working with complex 
parameterized types.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bjava'>
+        *      <jc>// Working with complex generic types</jc>
+        *      Cache2&lt;Class&lt;?&gt;,Class&lt;? extends 
Annotation&gt;,List&lt;Annotation&gt;&gt; <jv>cache</jv> =
+        *              Cache2.&lt;Class&lt;?&gt;,Class&lt;? extends 
Annotation&gt;,List&lt;Annotation&gt;&gt;<jsm>create</jsm>()
+        *                      .supplier((k1, k2) -&gt; findAnnotations(k1, 
k2))
+        *                      .build();
+        * </p>
+        *
+        * @param <K1> The first key type.
+        * @param <K2> The second key type.
+        * @param <V> The value type.
+        * @return A new builder for configuring the cache.
+        */
+       public static <K1,K2,V> Builder<K1,K2,V> create() {
+               return new Builder<>();
+       }
+
        /**
         * Creates a new {@link Builder} for constructing a cache.
         *
@@ -324,11 +369,11 @@ public class Cache2<K1,K2,V> extends 
ConcurrentHashMap2Key<K1,K2,V> {
         * @param <V> The value type.
         * @param key1 The first key type class (used for type safety).
         * @param key2 The second key type class (used for type safety).
-        * @param type The value type class (used for logging and type safety).
+        * @param type The value type class.
         * @return A new builder for configuring the cache.
         */
        public static <K1,K2,V> Builder<K1,K2,V> of(Class<K1> key1, Class<K2> 
key2, Class<V> type) {
-               return new Builder<>(type);
+               return new Builder<>();
        }
 
        private final int maxSize;
@@ -346,7 +391,7 @@ public class Cache2<K1,K2,V> extends 
ConcurrentHashMap2Key<K1,K2,V> {
                this.disableCaching = builder.disableCaching;
                this.supplier = builder.supplier;
                if (builder.logOnExit) {
-                       shutdownMessage(() -> scn(builder.type) + " cache:  
hits=" + cacheHits.get() + ", misses: " + size());
+                       shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
index 9ab7fc0211..7eb912fee7 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache3.java
@@ -87,16 +87,17 @@ public class Cache3<K1,K2,K3,V> extends 
ConcurrentHashMap3Key<K1,K2,K3,V> {
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,V> {
-               boolean disableCaching, logOnExit;
+               boolean disableCaching;
                int maxSize;
-               Class<V> type;
+               String id;
+               boolean logOnExit;
                Function3<K1,K2,K3,V> supplier;
 
-               Builder(Class<V> type) {
-                       this.type = type;
+               Builder() {
                        disableCaching = env("juneau.cache.disable", false);
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
+                       id = "Cache3";
                }
 
                /**
@@ -132,10 +133,29 @@ public class Cache3<K1,K2,K3,V> extends 
ConcurrentHashMap3Key<K1,K2,K3,V> {
                /**
                 * Enables logging of cache statistics when the JVM exits.
                 *
+                * @param id The identifier to use in the log message.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,V> logOnExit() {
-                       logOnExit = true;
+               public Builder<K1,K2,K3,V> logOnExit(String id) {
+                       this.id = id;
+                       this.logOnExit = true;
+                       return this;
+               }
+
+               /**
+                * Conditionally enables logging of cache statistics when the 
JVM exits.
+                *
+                * <p>
+                * When enabled, the cache will register a shutdown hook that 
logs the cache name,
+                * total cache hits, and total cache misses (size of cache) to 
help analyze cache effectiveness.
+                *
+                * @param value Whether to enable logging on exit.
+                * @param id The identifier to use in the log message.
+                * @return This object for method chaining.
+                */
+               public Builder<K1,K2,K3,V> logOnExit(boolean value, String id) {
+                       this.id = id;
+                       this.logOnExit = value;
                        return this;
                }
 
@@ -162,6 +182,23 @@ public class Cache3<K1,K2,K3,V> extends 
ConcurrentHashMap3Key<K1,K2,K3,V> {
                }
        }
 
+       /**
+        * Creates a new {@link Builder} for constructing a cache with explicit 
type parameters.
+        *
+        * <p>
+        * This variant allows you to specify the cache's generic types 
explicitly without passing
+        * the class objects, which is useful when working with complex 
parameterized types.
+        *
+        * @param <K1> The first key type.
+        * @param <K2> The second key type.
+        * @param <K3> The third key type.
+        * @param <V> The value type.
+        * @return A new builder for configuring the cache.
+        */
+       public static <K1,K2,K3,V> Builder<K1,K2,K3,V> create() {
+               return new Builder<>();
+       }
+
        /**
         * Creates a new {@link Builder} for constructing a cache.
         *
@@ -172,11 +209,11 @@ public class Cache3<K1,K2,K3,V> extends 
ConcurrentHashMap3Key<K1,K2,K3,V> {
         * @param key1 The first key type class (used for type safety).
         * @param key2 The second key type class (used for type safety).
         * @param key3 The third key type class (used for type safety).
-        * @param type The value type class (used for logging and type safety).
+        * @param type The value type class.
         * @return A new builder for configuring the cache.
         */
        public static <K1,K2,K3,V> Builder<K1,K2,K3,V> of(Class<K1> key1, 
Class<K2> key2, Class<K3> key3, Class<V> type) {
-               return new Builder<>(type);
+               return new Builder<>();
        }
 
        private final int maxSize;
@@ -194,7 +231,7 @@ public class Cache3<K1,K2,K3,V> extends 
ConcurrentHashMap3Key<K1,K2,K3,V> {
                this.disableCaching = builder.disableCaching;
                this.supplier = builder.supplier;
                if (builder.logOnExit) {
-                       shutdownMessage(() -> scn(builder.type) + " cache:  
hits=" + cacheHits.get() + ", misses: " + size());
+                       shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
index b62eca06ca..bc96ec1d29 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache4.java
@@ -74,16 +74,17 @@ public class Cache4<K1,K2,K3,K4,V> extends 
ConcurrentHashMap4Key<K1,K2,K3,K4,V>
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,K4,V> {
-               boolean disableCaching, logOnExit;
+               boolean disableCaching;
                int maxSize;
-               Class<V> type;
+               String id;
+               boolean logOnExit;
                Function4<K1,K2,K3,K4,V> supplier;
 
-               Builder(Class<V> type) {
-                       this.type = type;
+               Builder() {
                        disableCaching = env("juneau.cache.disable", false);
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
+                       id = "Cache4";
                }
 
                /**
@@ -119,10 +120,29 @@ public class Cache4<K1,K2,K3,K4,V> extends 
ConcurrentHashMap4Key<K1,K2,K3,K4,V>
                /**
                 * Enables logging of cache statistics when the JVM exits.
                 *
+                * @param id The identifier to use in the log message.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,K4,V> logOnExit() {
-                       logOnExit = true;
+               public Builder<K1,K2,K3,K4,V> logOnExit(String id) {
+                       this.id = id;
+                       this.logOnExit = true;
+                       return this;
+               }
+
+               /**
+                * Conditionally enables logging of cache statistics when the 
JVM exits.
+                *
+                * <p>
+                * When enabled, the cache will register a shutdown hook that 
logs the cache name,
+                * total cache hits, and total cache misses (size of cache) to 
help analyze cache effectiveness.
+                *
+                * @param value Whether to enable logging on exit.
+                * @param id The identifier to use in the log message.
+                * @return This object for method chaining.
+                */
+               public Builder<K1,K2,K3,K4,V> logOnExit(boolean value, String 
id) {
+                       this.id = id;
+                       this.logOnExit = value;
                        return this;
                }
 
@@ -149,6 +169,24 @@ public class Cache4<K1,K2,K3,K4,V> extends 
ConcurrentHashMap4Key<K1,K2,K3,K4,V>
                }
        }
 
+       /**
+        * Creates a new {@link Builder} for constructing a cache with explicit 
type parameters.
+        *
+        * <p>
+        * This variant allows you to specify the cache's generic types 
explicitly without passing
+        * the class objects, which is useful when working with complex 
parameterized types.
+        *
+        * @param <K1> The first key type.
+        * @param <K2> The second key type.
+        * @param <K3> The third key type.
+        * @param <K4> The fourth key type.
+        * @param <V> The value type.
+        * @return A new builder for configuring the cache.
+        */
+       public static <K1,K2,K3,K4,V> Builder<K1,K2,K3,K4,V> create() {
+               return new Builder<>();
+       }
+
        /**
         * Creates a new {@link Builder} for constructing a cache.
         *
@@ -161,11 +199,11 @@ public class Cache4<K1,K2,K3,K4,V> extends 
ConcurrentHashMap4Key<K1,K2,K3,K4,V>
         * @param key2 The second key type class (used for type safety).
         * @param key3 The third key type class (used for type safety).
         * @param key4 The fourth key type class (used for type safety).
-        * @param type The value type class (used for logging and type safety).
+        * @param type The value type class.
         * @return A new builder for configuring the cache.
         */
        public static <K1,K2,K3,K4,V> Builder<K1,K2,K3,K4,V> of(Class<K1> key1, 
Class<K2> key2, Class<K3> key3, Class<K4> key4, Class<V> type) {
-               return new Builder<>(type);
+               return new Builder<>();
        }
 
        private final int maxSize;
@@ -183,7 +221,7 @@ public class Cache4<K1,K2,K3,K4,V> extends 
ConcurrentHashMap4Key<K1,K2,K3,K4,V>
                this.disableCaching = builder.disableCaching;
                this.supplier = builder.supplier;
                if (builder.logOnExit) {
-                       shutdownMessage(() -> scn(builder.type) + " cache:  
hits=" + cacheHits.get() + ", misses: " + size());
+                       shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
index 89ab0463b8..3596b28040 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/Cache5.java
@@ -77,16 +77,17 @@ public class Cache5<K1,K2,K3,K4,K5,V> extends 
ConcurrentHashMap5Key<K1,K2,K3,K4,
         * @param <V> The value type.
         */
        public static class Builder<K1,K2,K3,K4,K5,V> {
-               boolean disableCaching, logOnExit;
+               boolean disableCaching;
                int maxSize;
-               Class<V> type;
+               String id;
+               boolean logOnExit;
                Function5<K1,K2,K3,K4,K5,V> supplier;
 
-               Builder(Class<V> type) {
-                       this.type = type;
+               Builder() {
                        disableCaching = env("juneau.cache.disable", false);
                        maxSize = env("juneau.cache.maxSize", 1000);
                        logOnExit = env("juneau.cache.logOnExit", false);
+                       id = "Cache5";
                }
 
                /**
@@ -122,10 +123,29 @@ public class Cache5<K1,K2,K3,K4,K5,V> extends 
ConcurrentHashMap5Key<K1,K2,K3,K4,
                /**
                 * Enables logging of cache statistics when the JVM exits.
                 *
+                * @param id The identifier to use in the log message.
                 * @return This object for method chaining.
                 */
-               public Builder<K1,K2,K3,K4,K5,V> logOnExit() {
-                       logOnExit = true;
+               public Builder<K1,K2,K3,K4,K5,V> logOnExit(String id) {
+                       this.id = id;
+                       this.logOnExit = true;
+                       return this;
+               }
+
+               /**
+                * Conditionally enables logging of cache statistics when the 
JVM exits.
+                *
+                * <p>
+                * When enabled, the cache will register a shutdown hook that 
logs the cache name,
+                * total cache hits, and total cache misses (size of cache) to 
help analyze cache effectiveness.
+                *
+                * @param value Whether to enable logging on exit.
+                * @param id The identifier to use in the log message.
+                * @return This object for method chaining.
+                */
+               public Builder<K1,K2,K3,K4,K5,V> logOnExit(boolean value, 
String id) {
+                       this.id = id;
+                       this.logOnExit = value;
                        return this;
                }
 
@@ -152,6 +172,25 @@ public class Cache5<K1,K2,K3,K4,K5,V> extends 
ConcurrentHashMap5Key<K1,K2,K3,K4,
                }
        }
 
+       /**
+        * Creates a new {@link Builder} for constructing a cache with explicit 
type parameters.
+        *
+        * <p>
+        * This variant allows you to specify the cache's generic types 
explicitly without passing
+        * the class objects, which is useful when working with complex 
parameterized types.
+        *
+        * @param <K1> The first key type.
+        * @param <K2> The second key type.
+        * @param <K3> The third key type.
+        * @param <K4> The fourth key type.
+        * @param <K5> The fifth key type.
+        * @param <V> The value type.
+        * @return A new builder for configuring the cache.
+        */
+       public static <K1,K2,K3,K4,K5,V> Builder<K1,K2,K3,K4,K5,V> create() {
+               return new Builder<>();
+       }
+
        /**
         * Creates a new {@link Builder} for constructing a cache.
         *
@@ -166,11 +205,11 @@ public class Cache5<K1,K2,K3,K4,K5,V> extends 
ConcurrentHashMap5Key<K1,K2,K3,K4,
         * @param key3 The third key type class (used for type safety).
         * @param key4 The fourth key type class (used for type safety).
         * @param key5 The fifth key type class (used for type safety).
-        * @param type The value type class (used for logging and type safety).
+        * @param type The value type class.
         * @return A new builder for configuring the cache.
         */
        public static <K1,K2,K3,K4,K5,V> Builder<K1,K2,K3,K4,K5,V> of(Class<K1> 
key1, Class<K2> key2, Class<K3> key3, Class<K4> key4, Class<K5> key5, Class<V> 
type) {
-               return new Builder<>(type);
+               return new Builder<>();
        }
 
        private final int maxSize;
@@ -188,7 +227,7 @@ public class Cache5<K1,K2,K3,K4,K5,V> extends 
ConcurrentHashMap5Key<K1,K2,K3,K4,
                this.disableCaching = builder.disableCaching;
                this.supplier = builder.supplier;
                if (builder.logOnExit) {
-                       shutdownMessage(() -> scn(builder.type) + " cache:  
hits=" + cacheHits.get() + ", misses: " + size());
+                       shutdownMessage(() -> builder.id + ":  hits=" + 
cacheHits.get() + ", misses: " + size());
                }
        }
 
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
index 008cd06fe0..bfeb5a64ca 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider.java
@@ -33,7 +33,6 @@ import org.apache.juneau.common.collections.*;
  * <h5 class='section'>See Also:</h5><ul>
  * </ul>
  */
-@SuppressWarnings("rawtypes")
 public interface AnnotationProvider {
 
        /**
@@ -44,15 +43,14 @@ public interface AnnotationProvider {
        /**
         * Default metadata provider.
         */
-       @SuppressWarnings("unchecked")
        AnnotationProvider DEFAULT = new AnnotationProvider() {
 
                // @formatter:off
-               private final Cache2<Class<?>,Class<? extends 
Annotation>,List<Annotation>> classAnnotationCache = 
(Cache2)Cache2.of(Class.class, Class.class, 
List.class).disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1, k2) -> 
u(l(k1.getAnnotationsByType(k2)))).build();
-               private final Cache2<Class<?>,Class<? extends 
Annotation>,List<Annotation>> declaredClassAnnotationCache = 
(Cache2)Cache2.of(Class.class, Class.class, 
List.class).disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1, k2) -> 
u(l(k1.getDeclaredAnnotationsByType(k2)))).build();
-               private final Cache2<Method,Class<? extends 
Annotation>,List<Annotation>> methodAnnotationCache = 
(Cache2)Cache2.of(Method.class, Class.class, 
List.class).disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1, k2) -> 
u(l(k1.getAnnotationsByType(k2)))).build();
-               private final Cache2<Field,Class<? extends 
Annotation>,List<Annotation>> fieldAnnotationCache = 
(Cache2)Cache2.of(Field.class, Class.class, 
List.class).disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1, k2) -> 
u(l(k1.getAnnotationsByType(k2)))).build();
-               private final Cache2<Constructor<?>,Class<? extends 
Annotation>,List<Annotation>> constructorAnnotationCache = 
(Cache2)Cache2.of(Constructor.class, Class.class, 
List.class).disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1, k2) -> 
u(l(k1.getAnnotationsByType(k2)))).build();
+               private final Cache2<Class<?>,Class<? extends 
Annotation>,List<Annotation>> classAnnotationCache = Cache2.<Class<?>,Class<? 
extends 
Annotation>,List<Annotation>>create().disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1,
 k2) -> u(l(k1.getAnnotationsByType(k2)))).build();
+               private final Cache2<Class<?>,Class<? extends 
Annotation>,List<Annotation>> declaredClassAnnotationCache = 
Cache2.<Class<?>,Class<? extends 
Annotation>,List<Annotation>>create().disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1,
 k2) -> u(l(k1.getDeclaredAnnotationsByType(k2)))).build();
+               private final Cache2<Method,Class<? extends 
Annotation>,List<Annotation>> methodAnnotationCache = Cache2.<Method,Class<? 
extends 
Annotation>,List<Annotation>>create().disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1,
 k2) -> u(l(k1.getAnnotationsByType(k2)))).build();
+               private final Cache2<Field,Class<? extends 
Annotation>,List<Annotation>> fieldAnnotationCache = Cache2.<Field,Class<? 
extends 
Annotation>,List<Annotation>>create().disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1,
 k2) -> u(l(k1.getAnnotationsByType(k2)))).build();
+               private final Cache2<Constructor<?>,Class<? extends 
Annotation>,List<Annotation>> constructorAnnotationCache = 
Cache2.<Constructor<?>,Class<? extends 
Annotation>,List<Annotation>>create().disableCaching(DISABLE_ANNOTATION_CACHING).supplier((k1,
 k2) -> u(l(k1.getAnnotationsByType(k2)))).build();
                // @formatter:on
 
                @Override /* Overridden from AnnotationProvider */
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
index 3674c9ae99..d243e9c0c1 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
@@ -60,16 +60,9 @@ public class AnnotationProvider2 {
        public static final AnnotationProvider2 INSTANCE = new 
AnnotationProvider2();
 
        // @formatter:off
-       private final Cache<Class<?>,List<AnnotationInfo<Annotation>>> 
classAnnotationsInfo = _buildClassAnnotationsCache();
+       private final Cache<Class<?>,List<AnnotationInfo<Annotation>>> 
classAnnotationsInfo = 
Cache.<Class<?>,List<AnnotationInfo<Annotation>>>create().supplier(this::findClassAnnotations).disableCaching(DISABLE_ANNOTATION_CACHING).build();
        // @formatter:on
 
-       @SuppressWarnings("unchecked")
-       private Cache<Class<?>,List<AnnotationInfo<Annotation>>> 
_buildClassAnnotationsCache() {
-               var builder = Cache.of(Class.class, 
List.class).supplier(this::findClassAnnotations);
-               if (DISABLE_ANNOTATION_CACHING)
-                       builder.disableCaching();
-               return 
(Cache<Class<?>,List<AnnotationInfo<Annotation>>>)(Cache<?,?>)builder.build();
-       }
 
        
//-----------------------------------------------------------------------------------------------------------------
        // Public API
@@ -133,25 +126,25 @@ public class AnnotationProvider2 {
        private List<AnnotationInfo<Annotation>> findClassAnnotations(Class<?> 
forClass) {
                var ci = ClassInfo.of(forClass);
                var list = new ArrayList<AnnotationInfo<Annotation>>();
-               
+
                // On this class
                findDeclaredAnnotations(list, forClass);
-               
+
                // On parent classes ordered child-to-parent
                var parents = ci.getParents();
                for (int i = 0; i < parents.size(); i++)
                        findDeclaredAnnotations(list, parents.get(i).inner());
-               
+
                // On interfaces ordered child-to-parent
                var interfaces = ci.getInterfaces();
                for (int i = 0; i < interfaces.size(); i++)
                        findDeclaredAnnotations(list, 
interfaces.get(i).inner());
-               
+
                // On the package of this class
                var pkg = ci.getPackage();
                if (nn(pkg))
                        findDeclaredAnnotations(list, pkg.inner());
-               
+
                return u(list);
        }
 
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 0fac6f5522..3acae2067f 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
@@ -58,8 +58,8 @@ public class ParameterInfo extends ElementInfo implements 
Annotatable {
        private final int index;
        private final ClassInfo type;
 
-       @SuppressWarnings({"rawtypes"})
-       private final Cache foundAnnotations = Cache.of(Class.class, 
List.class).supplier(this::findAnnotationInfosInternal).build();
+       @SuppressWarnings({"rawtypes","unchecked"})
+       private final Cache<Class,List<AnnotationInfo<Annotation>>> 
foundAnnotations = 
Cache.<Class,List<AnnotationInfo<Annotation>>>create().supplier((k) -> 
findAnnotationInfosInternal(k)).build();
 
        private final Supplier<List<AnnotationInfo<Annotation>>> annotations = 
memoize(this::_findAnnotations);
        private final Supplier<List<ParameterInfo>> matchingParameters = 
memoize(this::_findMatchingParameters);
@@ -215,9 +215,9 @@ public class ParameterInfo extends ElementInfo implements 
Annotatable {
         * @param type The annotation type to look for.
         * @return A list of annotation infos found, or an empty list if none 
found.
         */
-       @SuppressWarnings("unchecked")
+       @SuppressWarnings({ "unchecked", "rawtypes" })
        public <A extends Annotation> List<AnnotationInfo<A>> 
findAnnotationInfos(Class<A> type) {
-               return (List<AnnotationInfo<A>>)foundAnnotations.get(type);
+               return (List)foundAnnotations.get(type);
        }
 
        /**
diff --git 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
index dfdf7ea36a..e10de92b86 100644
--- 
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
+++ 
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/MimeTypeDetector.java
@@ -263,7 +263,7 @@ public class MimeTypeDetector {
                        cacheBuilder.disableCaching();
                }
                if (builder.cacheLogOnExit) {
-                       cacheBuilder.logOnExit();
+                       cacheBuilder.logOnExit("MimeTypeDetector");
                }
 
                this.cache = cacheBuilder.build();

Reply via email to