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 3f871dae3b Utility class modernization
3f871dae3b is described below
commit 3f871dae3b25a3cf273d3e9ce951670358c0fb3e
Author: James Bognar <[email protected]>
AuthorDate: Wed Nov 5 10:48:22 2025 -0500
Utility class modernization
---
.../juneau/common/collections/MapBuilder.java | 102 ++++++++++--
.../juneau/common/reflect/AnnotationProvider2.java | 184 +++++++++++++++++++++
.../juneau/common/reflect}/ReflectionMap.java | 106 ++++++------
.../juneau/common/utils/CollectionUtils.java | 36 +++-
.../apache/juneau/rest/debug/DebugEnablement.java | 2 +-
.../juneau/rest/debug/DebugEnablementMap.java | 2 +-
.../reflect}/ReflectionMapTest.java | 30 ++--
7 files changed, 380 insertions(+), 82 deletions(-)
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/MapBuilder.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/MapBuilder.java
index bccfa60cd8..c028470d6c 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/MapBuilder.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/collections/MapBuilder.java
@@ -32,12 +32,17 @@ import org.apache.juneau.common.utils.*;
* other maps, sorting by keys, and applying modifiers like unmodifiable or
sparse modes. It's particularly
* useful when constructing maps dynamically from multiple sources or with
conditional entries.
*
+ * <p>
+ * Instances of this builder can be created using {@link #create(Class,
Class)} or the convenience method
+ * {@link org.apache.juneau.common.utils.CollectionUtils#mapb(Class, Class,
org.apache.juneau.common.utils.Converter...)}.
+ *
* <h5 class='section'>Features:</h5>
* <ul class='spaced-list'>
* <li>Fluent API - all methods return <c>this</c> for method chaining
* <li>Multiple add methods - single entries, pairs, other maps
* <li>Arbitrary input support - automatic type conversion with {@link
#addAny(Object...)}
* <li>Pair adding - {@link #addPairs(Object...)} for varargs key-value
pairs
+ * <li>Filtering support - exclude unwanted values via {@link #filtered()}
or {@link #filtered(java.util.function.Predicate)}
* <li>Sorting support - natural key order or custom {@link Comparator}
* <li>Sparse mode - return <jk>null</jk> for empty maps
* <li>Unmodifiable mode - create immutable maps
@@ -46,20 +51,22 @@ import org.apache.juneau.common.utils.*;
*
* <h5 class='section'>Examples:</h5>
* <p class='bjava'>
+ * <jk>import static</jk> org.apache.juneau.common.utils.CollectionUtils.*;
+ *
* <jc>// Basic usage</jc>
- * Map<String,Integer> <jv>map</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
+ * Map<String,Integer> <jv>map</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
* .add(<js>"one"</js>, 1)
* .add(<js>"two"</js>, 2)
* .add(<js>"three"</js>, 3)
* .build();
*
* <jc>// Using pairs</jc>
- * Map<String,String> <jv>props</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
+ * Map<String,String> <jv>props</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
* .addPairs(<js>"host"</js>, <js>"localhost"</js>,
<js>"port"</js>, <js>"8080"</js>)
* .build();
*
* <jc>// With sorting by key</jc>
- * Map<String,Integer> <jv>sorted</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
+ * Map<String,Integer> <jv>sorted</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
* .add(<js>"zebra"</js>, 3)
* .add(<js>"apple"</js>, 1)
* .add(<js>"banana"</js>, 2)
@@ -67,7 +74,7 @@ import org.apache.juneau.common.utils.*;
* .build(); <jc>// Returns TreeMap with natural key order</jc>
*
* <jc>// Immutable map</jc>
- * Map<String,String> <jv>config</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
+ * Map<String,String> <jv>config</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
* .add(<js>"env"</js>, <js>"prod"</js>)
* .add(<js>"region"</js>, <js>"us-west"</js>)
* .unmodifiable()
@@ -75,13 +82,13 @@ import org.apache.juneau.common.utils.*;
*
* <jc>// From multiple sources</jc>
* Map<String,Integer> <jv>existing</jv> = Map.of(<js>"a"</js>, 1,
<js>"b"</js>, 2);
- * Map<String,Integer> <jv>combined</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
+ * Map<String,Integer> <jv>combined</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, Integer.<jk>class</jk>)
* .addAll(<jv>existing</jv>)
* .add(<js>"c"</js>, 3)
* .build();
*
* <jc>// Sparse mode - returns null when empty</jc>
- * Map<String,String> <jv>maybeNull</jv> =
MapBuilder.<jsm>create</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
+ * Map<String,String> <jv>maybeNull</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
* .sparse()
* .build(); <jc>// Returns null, not empty map</jc>
* </p>
@@ -105,6 +112,7 @@ public class MapBuilder<K,V> {
private Map<K,V> map;
private boolean unmodifiable = false, sparse = false;
private Comparator<K> comparator;
+ private java.util.function.Predicate<Object> filter;
private Class<K> keyType;
private Class<V> valueType;
@@ -151,11 +159,17 @@ public class MapBuilder<K,V> {
/**
* Adds a single entry to this map.
*
+ * <p>
+ * If a filter has been set via {@link
#filtered(java.util.function.Predicate)} or {@link #filtered()},
+ * the value will only be added if it passes the filter (i.e., the
filter returns {@code true}).
+ *
* @param key The map key.
* @param value The map value.
* @return This object.
*/
public MapBuilder<K,V> add(K key, V value) {
+ if (filter != null && !filter.test(value))
+ return this;
if (map == null)
map = new LinkedHashMap<>();
map.put(key, value);
@@ -168,15 +182,16 @@ public class MapBuilder<K,V> {
* <p>
* This is a no-op if the value is <jk>null</jk>.
*
+ * <p>
+ * If a filter has been set, each value will be filtered before being
added.
+ *
* @param value The map to add to this map.
* @return This object.
*/
public MapBuilder<K,V> addAll(Map<K,V> value) {
if (nn(value)) {
- if (map == null)
- map = new LinkedHashMap<>(value);
- else
- map.putAll(value);
+ for (Map.Entry<K,V> entry : value.entrySet())
+ add(entry.getKey(), entry.getValue());
}
return this;
}
@@ -308,6 +323,73 @@ public class MapBuilder<K,V> {
return this;
}
+ /**
+ * Applies a filter predicate to values added via {@link #add(Object,
Object)}.
+ *
+ * <p>
+ * Values where the predicate returns {@code true} will be kept; values
where it returns {@code false} will not be added.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jk>import static</jk>
org.apache.juneau.common.utils.CollectionUtils.*;
+ *
+ * <jc>// Keep only non-null, non-empty string values</jc>
+ * Map<String,String> <jv>map</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, String.<jk>class</jk>)
+ * .filtered(<jv>x</jv> -> <jv>x</jv> != <jk>null</jk>
&& !<jv>x</jv>.equals(<js>""</js>))
+ * .add(<js>"a"</js>, <js>"foo"</js>)
+ * .add(<js>"b"</js>, <jk>null</jk>) <jc>// Not
added</jc>
+ * .add(<js>"c"</js>, <js>""</js>) <jc>// Not
added</jc>
+ * .build();
+ * </p>
+ *
+ * @param filter The filter predicate.
+ * @return This object.
+ */
+ public MapBuilder<K,V> filtered(java.util.function.Predicate<Object>
filter) {
+ this.filter = filter;
+ return this;
+ }
+
+ /**
+ * Applies a default filter that excludes common "empty" or "unset"
values from being added to the map.
+ *
+ * <p>
+ * The following values are filtered out:
+ * <ul>
+ * <li>{@code null}
+ * <li>{@link Boolean#FALSE}
+ * <li>Numbers with {@code intValue() == -1}
+ * <li>Empty arrays
+ * <li>Empty {@link Map Maps}
+ * <li>Empty {@link Collection Collections}
+ * </ul>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * <jk>import static</jk>
org.apache.juneau.common.utils.CollectionUtils.*;
+ *
+ * Map<String,Object> <jv>map</jv> =
<jsm>mapb</jsm>(String.<jk>class</jk>, Object.<jk>class</jk>)
+ * .filtered()
+ * .add(<js>"name"</js>, <js>"John"</js>)
+ * .add(<js>"age"</js>, -1) <jc>// Not
added</jc>
+ * .add(<js>"enabled"</js>, <jk>false</jk>) <jc>// Not
added</jc>
+ * .add(<js>"tags"</js>, <jk>new</jk> String[0]) <jc>//
Not added</jc>
+ * .build();
+ * </p>
+ *
+ * @return This object.
+ */
+ public MapBuilder<K,V> filtered() {
+ return filtered(x -> ! (
+ x == null
+ || (x instanceof Boolean && x.equals(false))
+ || (x instanceof Number && ((Number)x).intValue() == -1)
+ || (isArray(x) && java.lang.reflect.Array.getLength(x)
== 0)
+ || (x instanceof Map && ((Map<?,?>)x).isEmpty())
+ || (x instanceof Collection &&
((Collection<?>)x).isEmpty())
+ ));
+ }
+
/**
* Converts the set into a {@link SortedMap}.
*
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
new file mode 100644
index 0000000000..3674c9ae99
--- /dev/null
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/AnnotationProvider2.java
@@ -0,0 +1,184 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.common.reflect;
+
+import static org.apache.juneau.common.utils.AssertionUtils.*;
+import static org.apache.juneau.common.utils.ClassUtils.*;
+import static org.apache.juneau.common.utils.CollectionUtils.*;
+import static org.apache.juneau.common.utils.Utils.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.stream.*;
+
+import org.apache.juneau.common.collections.*;
+
+/**
+ * Enhanced annotation provider for classes that returns {@link
AnnotationInfo} objects instead of raw {@link Annotation} objects.
+ *
+ * <p>
+ * This class provides a modern API for retrieving class annotations with the
following benefits:
+ * <ul>
+ * <li>Returns {@link AnnotationInfo} wrappers that provide additional
methods and type safety
+ * <li>Supports filtering by annotation type using streams
+ * <li>Properly handles repeatable annotations
+ * <li>Searches up the class hierarchy (class → parents → interfaces →
package)
+ * <li>Caches results for performance
+ * </ul>
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ * <li class='jc'>{@link AnnotationProvider}
+ * <li class='jc'>{@link AnnotationInfo}
+ * </ul>
+ */
+public class AnnotationProvider2 {
+
+ /**
+ * Disable annotation caching.
+ */
+ private static final boolean DISABLE_ANNOTATION_CACHING =
Boolean.getBoolean("juneau.disableAnnotationCaching");
+
+ /**
+ * Default instance.
+ */
+ public static final AnnotationProvider2 INSTANCE = new
AnnotationProvider2();
+
+ // @formatter:off
+ private final Cache<Class<?>,List<AnnotationInfo<Annotation>>>
classAnnotationsInfo = _buildClassAnnotationsCache();
+ // @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
+
//-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Finds all annotations on the specified class.
+ *
+ * <p>
+ * Returns annotations in child-to-parent order.
+ *
+ * @param onClass The class to search on.
+ * @return A list of {@link AnnotationInfo} objects representing
annotations on the specified class and its parents.
+ * Never <jk>null</jk>.
+ */
+ public List<AnnotationInfo<Annotation>> find(Class<?> onClass) {
+ assertArgNotNull("onClass", onClass);
+ return classAnnotationsInfo.get(onClass);
+ }
+
+ /**
+ * Finds all annotations of the specified type on the specified class.
+ *
+ * <p>
+ * Returns annotations in child-to-parent order.
+ *
+ * @param <A> The annotation type to find.
+ * @param type The annotation type to find.
+ * @param onClass The class to search on.
+ * @return A stream of {@link AnnotationInfo} objects representing
annotations of the specified type on the specified class and its parents.
+ * Never <jk>null</jk>.
+ */
+ @SuppressWarnings("unchecked")
+ public <A extends Annotation> Stream<AnnotationInfo<A>> find(Class<A>
type, Class<?> onClass) {
+ assertArgNotNull("type", type);
+ assertArgNotNull("onClass", onClass);
+ return find(onClass).stream()
+ .filter(a -> a.isType(type))
+ .map(a -> (AnnotationInfo<A>)a);
+ }
+
+
//-----------------------------------------------------------------------------------------------------------------
+ // Private implementation
+
//-----------------------------------------------------------------------------------------------------------------
+
+ /**
+ * Finds all annotations on the specified class in child-to-parent
order.
+ *
+ * <p>
+ * Annotations are appended in the following order:
+ * <ol>
+ * <li>On this class.
+ * <li>On parent classes ordered child-to-parent.
+ * <li>On interfaces ordered child-to-parent.
+ * <li>On the package of this class.
+ * </ol>
+ *
+ * @param forClass The class to find annotations on.
+ * @return A list of {@link AnnotationInfo} objects in child-to-parent
order.
+ */
+ 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);
+ }
+
+ /**
+ * Finds all declared annotations on the specified class and appends
them to the list.
+ *
+ * @param appendTo The list to append to.
+ * @param forClass The class to find declared annotations on.
+ */
+ private void findDeclaredAnnotations(List<AnnotationInfo<Annotation>>
appendTo, Class<?> forClass) {
+ var ci = ClassInfo.of(forClass);
+ for (var a : forClass.getDeclaredAnnotations())
+ for (var a2 : splitRepeated(a))
+ appendTo.add(AnnotationInfo.of(ci, a2));
+ }
+
+ /**
+ * Finds all annotations on the specified package and appends them to
the list.
+ *
+ * @param appendTo The list to append to.
+ * @param forPackage The package to find annotations on.
+ */
+ private void findDeclaredAnnotations(List<AnnotationInfo<Annotation>>
appendTo, Package forPackage) {
+ var pi = PackageInfo.of(forPackage);
+ for (var a : forPackage.getAnnotations())
+ for (var a2 : splitRepeated(a))
+ appendTo.add(AnnotationInfo.of(pi, a2));
+ }
+}
+
diff --git
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
similarity index 94%
rename from
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
rename to
juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
index b30319c4ef..9865a62f4c 100644
---
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ReflectionMap.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
@@ -14,10 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.juneau.utils;
+package org.apache.juneau.common.reflect;
import static java.lang.Character.*;
-import static org.apache.juneau.collections.JsonMap.*;
import static org.apache.juneau.common.utils.CollectionUtils.*;
import static org.apache.juneau.common.utils.StringUtils.*;
import static org.apache.juneau.common.utils.ThrowableUtils.*;
@@ -248,16 +247,16 @@ public class ReflectionMap<V> {
return classMatches(simpleName, fullName, c);
}
- @Override
- public String toString() {
- // @formatter:off
- return filteredMap()
- .append("simpleName", simpleName)
- .append("fullName", fullName)
- .append("value", value)
- .asString();
- // @formatter:on
- }
+ @Override
+ public String toString() {
+ // @formatter:off
+ return mapb().filtered()
+ .add("simpleName", simpleName)
+ .add("fullName", fullName)
+ .add("value", value)
+ .toString();
+ // @formatter:on
+ }
}
static class ConstructorEntry<V> {
@@ -280,17 +279,17 @@ public class ReflectionMap<V> {
return classMatches(simpleClassName, fullClassName, c)
&& (argsMatch(args, m.getParameterTypes()));
}
- @Override
- public String toString() {
- // @formatter:off
- return filteredMap()
- .append("simpleClassName", simpleClassName)
- .append("fullClassName", fullClassName)
- .append("args", args)
- .append("value", value)
- .asString();
- // @formatter:on
- }
+ @Override
+ public String toString() {
+ // @formatter:off
+ return mapb().filtered()
+ .add("simpleClassName", simpleClassName)
+ .add("fullClassName", fullClassName)
+ .add("args", args)
+ .add("value", value)
+ .toString();
+ // @formatter:on
+ }
}
static class FieldEntry<V> {
@@ -314,17 +313,17 @@ public class ReflectionMap<V> {
return classMatches(simpleClassName, fullClassName, c)
&& (eq(f.getName(), fieldName));
}
- @Override
- public String toString() {
- // @formatter:off
- return filteredMap()
- .append("simpleClassName", simpleClassName)
- .append("fullClassName", fullClassName)
- .append("fieldName", fieldName)
- .append("value", value)
- .asString();
- // @formatter:on
- }
+ @Override
+ public String toString() {
+ // @formatter:off
+ return mapb().filtered()
+ .add("simpleClassName", simpleClassName)
+ .add("fullClassName", fullClassName)
+ .add("fieldName", fieldName)
+ .add("value", value)
+ .toString();
+ // @formatter:on
+ }
}
static class MethodEntry<V> {
@@ -379,18 +378,18 @@ public class ReflectionMap<V> {
// @formatter:on
}
- @Override
- public String toString() {
- // @formatter:off
- return filteredMap()
- .append("simpleClassName", simpleClassName)
- .append("fullClassName", fullClassName)
- .append("methodName", methodName)
- .append("args", args)
- .append("value", value)
- .asString();
- // @formatter:on
- }
+ @Override
+ public String toString() {
+ // @formatter:off
+ return mapb().filtered()
+ .add("simpleClassName", simpleClassName)
+ .add("fullClassName", fullClassName)
+ .add("methodName", methodName)
+ .add("args", args)
+ .add("value", value)
+ .toString();
+ // @formatter:on
+ }
}
/**
@@ -811,12 +810,13 @@ public class ReflectionMap<V> {
@Override /* Overridden from Object */
public String toString() {
// @formatter:off
- return filteredMap()
- .append("classEntries", classEntries)
- .append("methodEntries", methodEntries)
- .append("fieldEntries", fieldEntries)
- .append("constructorEntries", constructorEntries)
- .asString();
+ return mapb().filtered()
+ .add("classEntries", classEntries)
+ .add("methodEntries", methodEntries)
+ .add("fieldEntries", fieldEntries)
+ .add("constructorEntries", constructorEntries)
+ .toString();
// @formatter:on
}
-}
\ No newline at end of file
+}
+
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/CollectionUtils.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/CollectionUtils.java
index 66c6725e59..de1211abf5 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/CollectionUtils.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/utils/CollectionUtils.java
@@ -1195,6 +1195,38 @@ public class CollectionUtils {
return MapBuilder.create(keyType,
valueType).converters(converters);
}
+ /**
+ * Convenience factory for a {@link MapBuilder} with {@link String}
keys and {@link Object} values.
+ *
+ * <p>
+ * This is a shortcut for <c>MapBuilder.create(String.<jk>class</jk>,
Object.<jk>class</jk>)</c>.
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bjava'>
+ * Map<String,Object> <jv>map</jv> = mapb()
+ * .add(<js>"foo"</js>, 1)
+ * .add(<js>"bar"</js>, 2)
+ * .build();
+ * </p>
+ *
+ * <p>
+ * This builder supports optional filtering to automatically exclude
unwanted values:
+ * <p class='bjava'>
+ * <jc>// Build a map excluding null and empty values</jc>
+ * Map<String,Object> <jv>map</jv> = mapb().filtered()
+ * .add(<js>"foo"</js>, <jk>null</jk>) <jc>//
Excluded</jc>
+ * .add(<js>"bar"</js>, <js>""</js>) <jc>//
Excluded</jc>
+ * .add(<js>"baz"</js>, <js>"value"</js>) <jc>//
Included</jc>
+ * .build();
+ * </p>
+ *
+ * @return A new map builder.
+ * @see MapBuilder
+ */
+ public static MapBuilder<String,Object> mapb() {
+ return MapBuilder.create(String.class, Object.class);
+ }
+
/**
* Creates a new {@link TreeSet} containing a copy of the specified set.
*
@@ -2159,10 +2191,10 @@ public class CollectionUtils {
* <h5 class='section'>Example:</h5>
* <p class='bjava'>
* String[] <jv>array</jv> = {<js>"a"</js>, <js>"b"</js>,
<js>"c"</js>};
- *
+ *
* <jc>// Prints "a", "b", "c"</jc>
*
<jsm>stream</jsm>(<jv>array</jv>).forEach(System.<jk>out</jk>::println);
- *
+ *
* <jc>// Handles null gracefully - returns empty stream</jc>
*
<jsm>stream</jsm>(<jk>null</jk>).forEach(System.<jk>out</jk>::println); <jc>//
Prints nothing</jc>
* </p>
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
index 9ed343c1ee..99c33132c7 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablement.java
@@ -24,11 +24,11 @@ import java.lang.reflect.Method;
import java.util.function.*;
import org.apache.juneau.*;
+import org.apache.juneau.common.reflect.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.http.response.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.utils.*;
import jakarta.servlet.http.*;
diff --git
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablementMap.java
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablementMap.java
index 451e318c60..2eb384c6ce 100644
---
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablementMap.java
+++
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/debug/DebugEnablementMap.java
@@ -17,7 +17,7 @@
package org.apache.juneau.rest.debug;
import org.apache.juneau.*;
-import org.apache.juneau.utils.*;
+import org.apache.juneau.common.reflect.*;
/**
* A reflection map for the {@link Enablement} setting.
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
similarity index 91%
rename from
juneau-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
rename to
juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
index ceafc780d4..23ffa281c4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/utils/ReflectionMapTest.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.juneau.utils;
+package org.apache.juneau.common.reflect;
import static org.apache.juneau.TestUtils.*;
import static org.apache.juneau.junit.bct.BctAssertions.*;
@@ -48,7 +48,7 @@ class ReflectionMapTest extends TestBase {
static ReflectionMap<Number>
A1_SIMPLE = create().append("A1", 1).build(),
A1b_SIMPLE = create().append("ReflectionMapTest$A1", 1).build(),
- A1_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$A1", 1).build(); //
Note this could be a static field.
+ A1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$A1",
1).build(); // Note this could be a static field.
@Test void a01_classNames_checkEntries() {
checkEntries(A1_SIMPLE, true, false, false, false);
@@ -109,12 +109,12 @@ class ReflectionMapTest extends TestBase {
B1m1ss_SIMPLE = create().append("B1.m1(java.lang.String)",
1).build(),
B1m1si_SIMPLE = create().append("B1.m1(String,int)", 1).build(),
B1m1ssi_SIMPLE = create().append("B1.m1(java.lang.String ,
int)", 1).build(),
- B1m1_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1", 1).build(),
- B1m1i_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1(int)",
1).build(),
- B1m1s_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1(String)",
1).build(),
- B1m1ss_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1(java.lang.String)",
1).build(),
- B1m1si_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1(String,int)",
1).build(),
- B1m1ssi_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$B1.m1(java.lang.String
, int)", 1).build();
+ B1m1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1",
1).build(),
+ B1m1i_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(int)",
1).build(),
+ B1m1s_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(String)",
1).build(),
+ B1m1ss_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(java.lang.String)",
1).build(),
+ B1m1si_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(String,int)",
1).build(),
+ B1m1ssi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$B1.m1(java.lang.String
, int)", 1).build();
@Test void b01_methodNames_checkEntries() {
checkEntries(B1m1_SIMPLE, false, true, true, false);
@@ -199,7 +199,7 @@ class ReflectionMapTest extends TestBase {
static ReflectionMap<Number>
C1f1_SIMPLE = create().append("C1.f1", 1).build(),
- C1f1_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$C1.f1", 1).build();
+ C1f1_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$C1.f1",
1).build();
@Test void c01_fieldNames_checkEntries() {
checkEntries(C1f1_SIMPLE, false, true, true, false);
@@ -245,12 +245,12 @@ class ReflectionMapTest extends TestBase {
Dss_SIMPLE = create().append("D1(java.lang.String)", 1).build(),
Dsi_SIMPLE = create().append("D1(String, int)", 1).build(),
Dssi_SIMPLE = create().append("D1(java.lang.String, int)",
1).build(),
- D_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1()", 1).build(),
- Di_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1(int)", 1).build(),
- Ds_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1(String)",
1).build(),
- Dss_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1(java.lang.String)",
1).build(),
- Dsi_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1(String, int)",
1).build(),
- Dssi_FULL =
create().append("org.apache.juneau.utils.ReflectionMapTest$D1(java.lang.String,
int)", 1).build();
+ D_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1()",
1).build(),
+ Di_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(int)",
1).build(),
+ Ds_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(String)",
1).build(),
+ Dss_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(java.lang.String)",
1).build(),
+ Dsi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(String,
int)", 1).build(),
+ Dssi_FULL =
create().append("org.apache.juneau.common.reflect.ReflectionMapTest$D1(java.lang.String,
int)", 1).build();
@Test void d01_constructorNames_checkEntries() {
checkEntries(D_SIMPLE, false, false, false, true);