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 8e7d6e9341 Utility class modernization
8e7d6e9341 is described below
commit 8e7d6e934187c3e8a7bf7c356c64701cab61531c
Author: James Bognar <[email protected]>
AuthorDate: Fri Nov 7 15:26:10 2025 -0500
Utility class modernization
---
.../juneau/common/reflect/AnnotationProvider.java | 4 +-
.../juneau/common/reflect/ReflectionMap.java | 385 +++++------
.../juneau/common/reflect/ReflectionMap2.java | 763 ---------------------
.../apache/juneau/rest/debug/DebugEnablement.java | 6 +-
.../juneau/rest/debug/DebugEnablementMap.java | 4 +-
.../juneau/common/reflect/ReflectionMapTest.java | 8 +-
6 files changed, 174 insertions(+), 996 deletions(-)
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 54ef0c396f..dfdd8c281d 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
@@ -209,7 +209,7 @@ public class AnnotationProvider {
*/
public static class Builder {
boolean disableCaching;
- ReflectionMap2.Builder<Annotation> runtimeAnnotations =
ReflectionMap2.create(Annotation.class);
+ ReflectionMap.Builder<Annotation> runtimeAnnotations =
ReflectionMap.create(Annotation.class);
Builder() {
disableCaching = DISABLE_ANNOTATION_CACHING;
@@ -407,7 +407,7 @@ public class AnnotationProvider {
private final Cache<Method,List<AnnotationInfo<Annotation>>>
methodAnnotations;
private final Cache<Field,List<AnnotationInfo<Annotation>>>
fieldAnnotations;
private final Cache<Constructor<?>,List<AnnotationInfo<Annotation>>>
constructorAnnotations;
- private final ReflectionMap2<Annotation> runtimeAnnotations;
+ private final ReflectionMap<Annotation> runtimeAnnotations;
// @formatter:on
/**
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
index 9865a62f4c..12bb5bf9f3 100644
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
+++
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap.java
@@ -25,6 +25,7 @@ import static org.apache.juneau.common.utils.Utils.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.function.*;
+import java.util.stream.*;
import org.apache.juneau.common.utils.*;
@@ -131,6 +132,7 @@ import org.apache.juneau.common.utils.*;
* @param <V> The type of object in this map.
*/
public class ReflectionMap<V> {
+
/**
* Builder class.
* @param <V> The type of object in this map.
@@ -247,16 +249,16 @@ public class ReflectionMap<V> {
return classMatches(simpleName, fullName, c);
}
- @Override
- public String toString() {
- // @formatter:off
- return mapb().filtered()
- .add("simpleName", simpleName)
- .add("fullName", fullName)
- .add("value", value)
- .toString();
- // @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> {
@@ -279,17 +281,17 @@ public class ReflectionMap<V> {
return classMatches(simpleClassName, fullClassName, c)
&& (argsMatch(args, m.getParameterTypes()));
}
- @Override
- public String toString() {
- // @formatter:off
- return mapb().filtered()
- .add("simpleClassName", simpleClassName)
- .add("fullClassName", fullClassName)
- .add("args", args)
- .add("value", value)
- .toString();
- // @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> {
@@ -313,17 +315,17 @@ public class ReflectionMap<V> {
return classMatches(simpleClassName, fullClassName, c)
&& (eq(f.getName(), fieldName));
}
- @Override
- public String toString() {
- // @formatter:off
- return mapb().filtered()
- .add("simpleClassName", simpleClassName)
- .add("fullClassName", fullClassName)
- .add("fieldName", fieldName)
- .add("value", value)
- .toString();
- // @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> {
@@ -378,18 +380,18 @@ public class ReflectionMap<V> {
// @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
- }
+ @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
+ }
}
/**
@@ -403,33 +405,6 @@ public class ReflectionMap<V> {
return new Builder<>();
}
- private static <V> List<V> lazyAdd(List<V> list, V v) {
- if (list == null)
- list = list();
- list.add(v);
- return list;
- }
-
- private static <V> List<V> lazyAdd(V[] array, List<V> list, V v) {
- if (list == null)
- list = list(array);
- list.add(v);
- return list;
- }
-
- @SuppressWarnings("unchecked")
- private static <V> V[] lazyArray(V[] array, List<V> list) {
- if (list == null)
- return array;
- array =
(V[])Array.newInstance(array.getClass().getComponentType(), list.size());
- list.toArray(array);
- return array;
- }
-
- private static <V> List<V> lazyList(List<V> list) {
- return list == null ? Collections.emptyList() : list;
- }
-
static boolean argsMatch(String[] names, Class<?>[] args) {
if (names == null)
return true;
@@ -498,93 +473,40 @@ public class ReflectionMap<V> {
}
}
- final ClassEntry<V>[] classEntries;
+ final List<ClassEntry<V>> classEntries;
- final MethodEntry<V>[] methodEntries;
+ final List<MethodEntry<V>> methodEntries;
- final FieldEntry<V>[] fieldEntries;
+ final List<FieldEntry<V>> fieldEntries;
- final ConstructorEntry<V>[] constructorEntries;
+ final List<ConstructorEntry<V>> constructorEntries;
/**
* Constructor.
*
* @param b Initializer object.
*/
- @SuppressWarnings("unchecked")
protected ReflectionMap(Builder<V> b) {
- this.classEntries = b.classEntries.toArray(new
ClassEntry[b.classEntries.size()]);
- this.methodEntries = b.methodEntries.toArray(new
MethodEntry[b.methodEntries.size()]);
- this.fieldEntries = b.fieldEntries.toArray(new
FieldEntry[b.fieldEntries.size()]);
- this.constructorEntries = b.constructorEntries.toArray(new
ConstructorEntry[b.constructorEntries.size()]);
+ this.classEntries = u(copyOf(b.classEntries));
+ this.methodEntries = u(copyOf(b.methodEntries));
+ this.fieldEntries = u(copyOf(b.fieldEntries));
+ this.constructorEntries = u(copyOf(b.constructorEntries));
}
- /**
- * Finds all values in this map that matches the specified class.
- *
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append values to.
- * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
- */
- public V[] appendAll(Class<?> c, Class<? extends V> ofType, V[] array) {
- List<V> list = null;
- for (var e : classEntries)
- if (e.matches(c) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(array, list, e.value);
- return lazyArray(array, list);
+ public Stream<V> findMatching(Class<?> c) {
+ return classEntries.stream().filter(x -> x.matches(c)).map(x ->
x.value);
}
- /**
- * Finds all values in this map that matches the specified constructor.
- *
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append values to.
- * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
- */
- public V[] appendAll(Constructor<?> c, Class<? extends V> ofType, V[]
array) {
- List<V> list = null;
- for (var e : constructorEntries)
- if (e.matches(c) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(array, list, e.value);
- return lazyArray(array, list);
+ public Stream<V> findMatching(Method m) {
+ return methodEntries.stream().filter(x -> x.matches(m)).map(x
-> x.value);
}
- /**
- * Finds all values in this map that matches the specified field.
- *
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append values to.
- * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
- */
- public V[] appendAll(Field f, Class<? extends V> ofType, V[] array) {
- List<V> list = null;
- for (var e : fieldEntries)
- if (e.matches(f) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(array, list, e.value);
- return lazyArray(array, list);
+ public Stream<V> findMatching(Field f) {
+ return fieldEntries.stream().filter(x -> x.matches(f)).map(x ->
x.value);
}
- /**
- * Finds all values in this map that matches the specified method.
- *
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append values to.
- * @return The same list passed in or a new modifiable list if
<jk>null</jk>.
- */
- public V[] appendAll(Method m, Class<? extends V> ofType, V[] array) {
- List<V> list = null;
- for (var e : methodEntries)
- if (e.matches(m) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(array, list, e.value);
- return lazyArray(array, list);
+ public Stream<V> findMatching(Constructor c) {
+ return constructorEntries.stream().filter(x ->
x.matches(c)).map(x -> x.value);
}
/**
@@ -605,11 +527,7 @@ public class ReflectionMap<V> {
* @return The matching object. Never <jk>null</jk>.
*/
public Optional<V> find(Class<?> c, Class<? extends V> ofType) {
- for (var e : classEntries)
- if (e.matches(c))
- if (ofType == null ||
ofType.isInstance(e.value))
- return opt(e.value);
- return opte();
+ return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
}
/**
@@ -630,11 +548,7 @@ public class ReflectionMap<V> {
* @return The matching object. Never <jk>null</jk>.
*/
public Optional<V> find(Constructor<?> c, Class<? extends V> ofType) {
- for (var e : constructorEntries)
- if (e.matches(c))
- if (ofType == null ||
ofType.isInstance(e.value))
- return opt(e.value);
- return opte();
+ return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
}
/**
@@ -655,11 +569,7 @@ public class ReflectionMap<V> {
* @return The matching object. Never <jk>null</jk>.
*/
public Optional<V> find(Field f, Class<? extends V> ofType) {
- for (var e : fieldEntries)
- if (e.matches(f))
- if (ofType == null ||
ofType.isInstance(e.value))
- return opt(e.value);
- return opte();
+ return opt(findMatching(f).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
}
/**
@@ -680,131 +590,163 @@ public class ReflectionMap<V> {
* @return The matching object. Never <jk>null</jk>.
*/
public Optional<V> find(Method m, Class<? extends V> ofType) {
- for (var e : methodEntries)
- if (e.matches(m))
- if (ofType == null ||
ofType.isInstance(e.value))
- return opt(e.value);
- return opte();
+ return opt(findMatching(m).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
}
/**
- * Finds all values in this map that matches the specified class.
+ * Finds all values in this map that match the specified class.
*
* @param c The class to test for.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Class<?> c) {
- List<V> list = null;
- for (var e : classEntries)
- if (e.matches(c) && nn(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findAll(c, null);
}
/**
- * Finds all values in this map that matches the specified class.
+ * Finds all values in this map that match the specified class.
*
* @param c The class to test for.
* @param ofType Only return objects of the specified type.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Class<?> c, Class<? extends V> ofType) {
- List<V> list = null;
- for (var e : classEntries)
- if (e.matches(c) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
}
/**
- * Finds all values in this map that matches the specified constructor.
+ * Finds all values in this map that match the specified constructor.
*
* @param c The constructor to test for.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Constructor<?> c) {
- List<V> list = null;
- for (var e : constructorEntries)
- if (e.matches(c) && nn(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findAll(c, null);
}
/**
- * Finds all values in this map that matches the specified constructor.
+ * Finds all values in this map that match the specified constructor.
*
* @param c The constructor to test for.
* @param ofType Only return objects of the specified type.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Constructor<?> c, Class<? extends V> ofType) {
- List<V> list = null;
- for (var e : constructorEntries)
- if (e.matches(c) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
}
/**
- * Finds all values in this map that matches the specified field.
+ * Finds all values in this map that match the specified field.
*
* @param f The field to test for.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Field f) {
- List<V> list = null;
- for (var e : fieldEntries)
- if (e.matches(f) && nn(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findAll(f, null);
}
/**
- * Finds all values in this map that matches the specified field.
+ * Finds all values in this map that match the specified field.
*
* @param f The field to test for.
* @param ofType Only return objects of the specified type.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Field f, Class<? extends V> ofType) {
- List<V> list = null;
- for (var e : fieldEntries)
- if (e.matches(f) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findMatching(f).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
}
/**
- * Finds all values in this map that matches the specified method.
+ * Finds all values in this map that match the specified method.
*
* @param m The method to test for.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Method m) {
- List<V> list = null;
- for (var e : methodEntries)
- if (e.matches(m) && nn(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findAll(m, null);
}
/**
- * Finds all values in this map that matches the specified method.
+ * Finds all values in this map that match the specified method.
*
* @param m The method to test for.
* @param ofType Only return objects of the specified type.
- * @return A modifiable list of matching values. Never <jk>null</jk>.
+ * @return The matching objects. Never <jk>null</jk>.
*/
public List<V> findAll(Method m, Class<? extends V> ofType) {
- List<V> list = null;
- for (var e : methodEntries)
- if (e.matches(m) && nn(e.value))
- if (ofType == null ||
ofType.isInstance(e.value))
- list = lazyAdd(list, e.value);
- return lazyList(list);
+ return findMatching(m).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
+ }
+
+ /**
+ * Finds all values in this map that match the specified class and
appends them to the specified array.
+ *
+ * @param c The class to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param array The array to append to.
+ * @return The array with matching objects appended.
+ */
+ public V[] appendAll(Class<?> c, Class<? extends V> ofType, V[] array) {
+ var list = findAll(c, ofType);
+ if (list.isEmpty())
+ return array;
+ var newArray = Arrays.copyOf(array, array.length + list.size());
+ for (int i = 0; i < list.size(); i++)
+ newArray[array.length + i] = list.get(i);
+ return newArray;
+ }
+
+ /**
+ * Finds all values in this map that match the specified constructor
and appends them to the specified array.
+ *
+ * @param c The constructor to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param array The array to append to.
+ * @return The array with matching objects appended.
+ */
+ public V[] appendAll(Constructor<?> c, Class<? extends V> ofType, V[]
array) {
+ var list = findAll(c, ofType);
+ if (list.isEmpty())
+ return array;
+ var newArray = Arrays.copyOf(array, array.length + list.size());
+ for (int i = 0; i < list.size(); i++)
+ newArray[array.length + i] = list.get(i);
+ return newArray;
+ }
+
+ /**
+ * Finds all values in this map that match the specified field and
appends them to the specified array.
+ *
+ * @param f The field to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param array The array to append to.
+ * @return The array with matching objects appended.
+ */
+ public V[] appendAll(Field f, Class<? extends V> ofType, V[] array) {
+ var list = findAll(f, ofType);
+ if (list.isEmpty())
+ return array;
+ var newArray = Arrays.copyOf(array, array.length + list.size());
+ for (int i = 0; i < list.size(); i++)
+ newArray[array.length + i] = list.get(i);
+ return newArray;
+ }
+
+ /**
+ * Finds all values in this map that match the specified method and
appends them to the specified array.
+ *
+ * @param m The method to test for.
+ * @param ofType Only return objects of the specified type.
+ * @param array The array to append to.
+ * @return The array with matching objects appended.
+ */
+ public V[] appendAll(Method m, Class<? extends V> ofType, V[] array) {
+ var list = findAll(m, ofType);
+ if (list.isEmpty())
+ return array;
+ var newArray = Arrays.copyOf(array, array.length + list.size());
+ for (int i = 0; i < list.size(); i++)
+ newArray[array.length + i] = list.get(i);
+ return newArray;
}
@Override /* Overridden from Object */
@@ -818,5 +760,4 @@ public class ReflectionMap<V> {
.toString();
// @formatter:on
}
-}
-
+}
\ No newline at end of file
diff --git
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap2.java
b/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap2.java
deleted file mode 100644
index 25cc709bed..0000000000
---
a/juneau-core/juneau-common/src/main/java/org/apache/juneau/common/reflect/ReflectionMap2.java
+++ /dev/null
@@ -1,763 +0,0 @@
-/*
- * 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 java.lang.Character.*;
-import static org.apache.juneau.common.utils.CollectionUtils.*;
-import static org.apache.juneau.common.utils.StringUtils.*;
-import static org.apache.juneau.common.utils.ThrowableUtils.*;
-import static org.apache.juneau.common.utils.Utils.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.function.*;
-import java.util.stream.*;
-
-import org.apache.juneau.common.utils.*;
-
-/**
- * Allows arbitrary objects to be mapped to classes and methods base on
class/method name keys.
- *
- * <p>
- * The valid pattern matches are:
- * <ul class='spaced-list'>
- * <li>Classes:
- * <ul>
- * <li>Fully qualified:
- * <ul>
- * <li><js>"com.foo.MyClass"</js>
- * </ul>
- * <li>Fully qualified inner class:
- * <ul>
- *
<li><js>"com.foo.MyClass$Inner1$Inner2"</js>
- * </ul>
- * <li>Simple:
- * <ul>
- * <li><js>"MyClass"</js>
- * </ul>
- * <li>Simple inner:
- * <ul>
- * <li><js>"MyClass$Inner1$Inner2"</js>
- * <li><js>"Inner1$Inner2"</js>
- * <li><js>"Inner2"</js>
- * </ul>
- * </ul>
- * <li>Methods:
- * <ul>
- * <li>Fully qualified with args:
- * <ul>
- *
<li><js>"com.foo.MyClass.myMethod(String,int)"</js>
- *
<li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js>
- *
<li><js>"com.foo.MyClass.myMethod()"</js>
- * </ul>
- * <li>Fully qualified:
- * <ul>
- * <li><js>"com.foo.MyClass.myMethod"</js>
- * </ul>
- * <li>Simple with args:
- * <ul>
- *
<li><js>"MyClass.myMethod(String,int)"</js>
- *
<li><js>"MyClass.myMethod(java.lang.String,int)"</js>
- * <li><js>"MyClass.myMethod()"</js>
- * </ul>
- * <li>Simple:
- * <ul>
- * <li><js>"MyClass.myMethod"</js>
- * </ul>
- * <li>Simple inner class:
- * <ul>
- *
<li><js>"MyClass$Inner1$Inner2.myMethod"</js>
- * <li><js>"Inner1$Inner2.myMethod"</js>
- * <li><js>"Inner2.myMethod"</js>
- * </ul>
- * </ul>
- * <li>Fields:
- * <ul>
- * <li>Fully qualified:
- * <ul>
- * <li><js>"com.foo.MyClass.myField"</js>
- * </ul>
- * <li>Simple:
- * <ul>
- * <li><js>"MyClass.myField"</js>
- * </ul>
- * <li>Simple inner class:
- * <ul>
- *
<li><js>"MyClass$Inner1$Inner2.myField"</js>
- * <li><js>"Inner1$Inner2.myField"</js>
- * <li><js>"Inner2.myField"</js>
- * </ul>
- * </ul>
- * <li>Constructors:
- * <ul>
- * <li>Fully qualified with args:
- * <ul>
- *
<li><js>"com.foo.MyClass(String,int)"</js>
- *
<li><js>"com.foo.MyClass(java.lang.String,int)"</js>
- * <li><js>"com.foo.MyClass()"</js>
- * </ul>
- * <li>Simple with args:
- * <ul>
- * <li><js>"MyClass(String,int)"</js>
- *
<li><js>"MyClass(java.lang.String,int)"</js>
- * <li><js>"MyClass()"</js>
- * </ul>
- * <li>Simple inner class:
- * <ul>
- * <li><js>"MyClass$Inner1$Inner2()"</js>
- * <li><js>"Inner1$Inner2()"</js>
- * <li><js>"Inner2()"</js>
- * </ul>
- * </ul>
- * <li>A comma-delimited list of anything on this list.
- * </ul>
- *
- * <h5 class='section'>See Also:</h5><ul>
- * </ul>
- *
- * @param <V> The type of object in this map.
- */
-public class ReflectionMap2<V> {
-
- /**
- * Builder class.
- * @param <V> The type of object in this map.
- */
- public static class Builder<V> {
- final List<ClassEntry<V>> classEntries;
- final List<MethodEntry<V>> methodEntries;
- final List<FieldEntry<V>> fieldEntries;
- final List<ConstructorEntry<V>> constructorEntries;
-
- /**
- * Constructor.
- */
- protected Builder() {
- classEntries = list();
- methodEntries = list();
- fieldEntries = list();
- constructorEntries = list();
- }
-
- /**
- * Copy constructor.
- *
- * @param copyFrom The builder being copied.
- */
- protected Builder(Builder<V> copyFrom) {
- classEntries = copyOf(copyFrom.classEntries);
- methodEntries = copyOf(copyFrom.methodEntries);
- fieldEntries = copyOf(copyFrom.fieldEntries);
- constructorEntries =
copyOf(copyFrom.constructorEntries);
- }
-
- /**
- * Adds a mapping to this builder.
- *
- * @param key
- * The mapping key.
- * <br>Can be any of the following:
- * <ul>
- * <li>Full class name (e.g.
<js>"com.foo.MyClass"</js>).
- * <li>Simple class name (e.g. <js>"MyClass"</js>).
- * <li>All classes (e.g. <js>"*"</js>).
- * <li>Full method name (e.g.
<js>"com.foo.MyClass.myMethod"</js>).
- * <li>Simple method name (e.g.
<js>"MyClass.myMethod"</js>).
- * <li>A comma-delimited list of anything on this
list.
- * </ul>
- * @param value The value for this mapping.
- * @return This object.
- */
- public Builder<V> append(String key, V value) {
- if (StringUtils.isEmpty(key))
- throw runtimeException("Invalid reflection
signature: [{0}]", key);
- try {
- splitNames(key, k -> {
- if (k.endsWith(")")) {
- int i = k.substring(0,
k.indexOf('(')).lastIndexOf('.');
- if (i == -1 ||
isUpperCase(k.charAt(i + 1))) {
-
constructorEntries.add(new ConstructorEntry<>(k, value));
- } else {
- methodEntries.add(new
MethodEntry<>(k, value));
- }
- } else {
- int i = k.lastIndexOf('.');
- if (i == -1) {
- classEntries.add(new
ClassEntry<>(k, value));
- } else if
(isUpperCase(k.charAt(i + 1))) {
- classEntries.add(new
ClassEntry<>(k, value));
- fieldEntries.add(new
FieldEntry<>(k, value));
- } else {
- methodEntries.add(new
MethodEntry<>(k, value));
- fieldEntries.add(new
FieldEntry<>(k, value));
- }
- }
- });
- } catch (@SuppressWarnings("unused")
IndexOutOfBoundsException e) {
- throw runtimeException("Invalid reflection
signature: [{0}]", key);
- }
-
- return this;
- }
-
- /**
- * Create new instance of {@link ReflectionMap2} based on the
contents of this builder.
- *
- * @return A new {@link ReflectionMap2} object.
- */
- public ReflectionMap2<V> build() {
- return new ReflectionMap2<>(this);
- }
-
- /**
- * Creates a copy of this builder.
- *
- * @return A copy of this builder.
- */
- public Builder<V> copy() {
- return new Builder<>(this);
- }
- }
-
- static class ClassEntry<V> {
- final String simpleName, fullName;
- final V value;
-
- ClassEntry(String name, V value) {
- this.simpleName = simpleClassName(name);
- this.fullName = name;
- this.value = value;
- }
-
- public boolean matches(Class<?> c) {
- if (c == null)
- return false;
- return classMatches(simpleName, fullName, c);
- }
-
- @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> {
- String simpleClassName, fullClassName, args[];
- V value;
-
- ConstructorEntry(String name, V value) {
- int i = name.indexOf('(');
- this.args = splita(name.substring(i + 1, name.length()
- 1));
- name = name.substring(0, i).trim();
- this.simpleClassName = simpleClassName(name);
- this.fullClassName = name;
- this.value = value;
- }
-
- public boolean matches(Constructor<?> m) {
- if (m == null)
- return false;
- var c = m.getDeclaringClass();
- return classMatches(simpleClassName, fullClassName, c)
&& (argsMatch(args, m.getParameterTypes()));
- }
-
- @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> {
- String simpleClassName, fullClassName, fieldName;
- V value;
-
- FieldEntry(String name, V value) {
- int i = name.lastIndexOf('.');
- var s1 = name.substring(0, i);
- var s2 = name.substring(i + 1);
- this.simpleClassName = simpleClassName(s1);
- this.fullClassName = s1;
- this.fieldName = s2;
- this.value = value;
- }
-
- public boolean matches(Field f) {
- if (f == null)
- return false;
- var c = f.getDeclaringClass();
- return classMatches(simpleClassName, fullClassName, c)
&& (eq(f.getName(), fieldName));
- }
-
- @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> {
- String simpleClassName, fullClassName, methodName, args[];
- V value;
-
- MethodEntry(String name, V value) {
- int i = name.indexOf('(');
- this.args = i == -1 ? null :
splitMethodArgs(name.substring(i + 1, name.length() - 1));
- if (nn(args)) {
- for (int j = 0; j < args.length; j++) {
-
- // Strip off generic parameters.
- int k = args[j].indexOf('<');
- if (k > 0)
- args[j] = args[j].substring(0,
k);
-
- // Convert from xxx[][] to [[Lxxx;
notation.
- if (args[j].endsWith("[]")) {
- int l = 0;
- while (args[j].endsWith("[]")) {
- l++;
- args[j] =
args[j].substring(0, args[j].length() - 2);
- }
- var sb = new
StringBuilder(args[j].length() + l + 2);
- for (int m = 0; m < l; m++)
- sb.append('[');
-
sb.append('L').append(args[j]).append(';');
- args[j] = sb.toString();
- }
- }
- }
- name = i == -1 ? name : name.substring(0, i);
- i = name.lastIndexOf('.');
- var s1 = name.substring(0, i).trim();
- var s2 = name.substring(i + 1).trim();
- this.simpleClassName = simpleClassName(s1);
- this.fullClassName = s1;
- this.methodName = s2;
- this.value = value;
- }
-
- public boolean matches(Method m) {
- if (m == null)
- return false;
- var c = m.getDeclaringClass();
- // @formatter:off
- return
- classMatches(simpleClassName, fullClassName, c)
- && (eq(m.getName(), methodName))
- && (argsMatch(args, m.getParameterTypes()));
- // @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
- }
- }
-
- /**
- * Static builder creator.
- *
- * @param <V> The type of object in this map.
- * @param c The type of object in this map.
- * @return A new instance of this object.
- */
- public static <V> Builder<V> create(Class<V> c) {
- return new Builder<>();
- }
-
- static boolean argsMatch(String[] names, Class<?>[] args) {
- if (names == null)
- return true;
- if (names.length != args.length)
- return false;
- for (int i = 0; i < args.length; i++) {
- var n = names[i];
- var a = args[i];
- if (! (eq(n, a.getSimpleName()) || eq(n, a.getName())))
- return false;
- }
- return true;
- }
-
- static boolean classMatches(String simpleName, String fullName,
Class<?> c) {
- // For class
org.apache.juneau.a.rttests.RountTripBeansWithBuilders$Ac$Builder
- // c.getSimpleName() == "Builder"
- // c.getFullName() ==
"org.apache.juneau.a.rttests.RountTripBeansWithBuilders$Ac$Builder"
- // c.getPackage() == "org.apache.juneau.a.rttests"
- var cSimple = scn(c);
- var cFull = cn(c);
- if (eq(simpleName, cSimple) || eq(fullName, cFull) ||
"*".equals(simpleName))
- return true;
- if (cFull.indexOf('$') != -1) {
- var p = c.getPackage();
- if (nn(p))
- cFull = cFull.substring(p.getName().length() +
1);
- if (eq(simpleName, cFull))
- return true;
- int i = cFull.indexOf('$');
- while (i != -1) {
- cFull = cFull.substring(i + 1);
- if (eq(simpleName, cFull))
- return true;
- i = cFull.indexOf('$');
- }
- }
- return false;
- }
-
- static String simpleClassName(String name) {
- int i = name.indexOf('.');
- if (i == -1)
- return name;
- return null;
- }
-
- static void splitNames(String key, Consumer<String> consumer) {
- if (key.indexOf(',') == -1) {
- consumer.accept(key);
- } else {
- int m = 0;
- boolean escaped = false;
- for (int i = 0; i < key.length(); i++) {
- char c = key.charAt(i);
- if (c == '(')
- escaped = true;
- else if (c == ')')
- escaped = false;
- else if (c == ',' && ! escaped) {
- consumer.accept(key.substring(m,
i).trim());
- m = i + 1;
- }
- }
- consumer.accept(key.substring(m).trim());
- }
- }
-
- final List<ClassEntry<V>> classEntries;
-
- final List<MethodEntry<V>> methodEntries;
-
- final List<FieldEntry<V>> fieldEntries;
-
- final List<ConstructorEntry<V>> constructorEntries;
-
- /**
- * Constructor.
- *
- * @param b Initializer object.
- */
- protected ReflectionMap2(Builder<V> b) {
- this.classEntries = u(copyOf(b.classEntries));
- this.methodEntries = u(copyOf(b.methodEntries));
- this.fieldEntries = u(copyOf(b.fieldEntries));
- this.constructorEntries = u(copyOf(b.constructorEntries));
- }
-
- public Stream<V> findMatching(Class<?> c) {
- return classEntries.stream().filter(x -> x.matches(c)).map(x ->
x.value);
- }
-
- public Stream<V> findMatching(Method m) {
- return methodEntries.stream().filter(x -> x.matches(m)).map(x
-> x.value);
- }
-
- public Stream<V> findMatching(Field f) {
- return fieldEntries.stream().filter(x -> x.matches(f)).map(x ->
x.value);
- }
-
- public Stream<V> findMatching(Constructor c) {
- return constructorEntries.stream().filter(x ->
x.matches(c)).map(x -> x.value);
- }
-
- /**
- * Finds first value in this map that matches the specified class.
- *
- * @param c The class to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Class<?> c) {
- return find(c, null);
- }
-
- /**
- * Finds first value in this map that matches the specified class.
- *
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Class<?> c, Class<? extends V> ofType) {
- return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified constructor.
- *
- * @param c The constructor to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Constructor<?> c) {
- return find(c, null);
- }
-
- /**
- * Finds first value in this map that matches the specified constructor.
- *
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Constructor<?> c, Class<? extends V> ofType) {
- return opt(findMatching(c).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified field.
- *
- * @param f The field to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Field f) {
- return find(f, null);
- }
-
- /**
- * Finds first value in this map that matches the specified field.
- *
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Field f, Class<? extends V> ofType) {
- return opt(findMatching(f).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds first value in this map that matches the specified method.
- *
- * @param m The method to test for.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Method m) {
- return find(m, null);
- }
-
- /**
- * Finds first value in this map that matches the specified method.
- *
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching object. Never <jk>null</jk>.
- */
- public Optional<V> find(Method m, Class<? extends V> ofType) {
- return opt(findMatching(m).filter(x -> x != null && (ofType ==
null || ofType.isInstance(x))).findFirst().orElse(null));
- }
-
- /**
- * Finds all values in this map that match the specified class.
- *
- * @param c The class to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Class<?> c) {
- return findAll(c, null);
- }
-
- /**
- * Finds all values in this map that match the specified class.
- *
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Class<?> c, Class<? extends V> ofType) {
- return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified constructor.
- *
- * @param c The constructor to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Constructor<?> c) {
- return findAll(c, null);
- }
-
- /**
- * Finds all values in this map that match the specified constructor.
- *
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Constructor<?> c, Class<? extends V> ofType) {
- return findMatching(c).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified field.
- *
- * @param f The field to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Field f) {
- return findAll(f, null);
- }
-
- /**
- * Finds all values in this map that match the specified field.
- *
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Field f, Class<? extends V> ofType) {
- return findMatching(f).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified method.
- *
- * @param m The method to test for.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Method m) {
- return findAll(m, null);
- }
-
- /**
- * Finds all values in this map that match the specified method.
- *
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @return The matching objects. Never <jk>null</jk>.
- */
- public List<V> findAll(Method m, Class<? extends V> ofType) {
- return findMatching(m).filter(x -> ofType == null ||
ofType.isInstance(x)).toList();
- }
-
- /**
- * Finds all values in this map that match the specified class and
appends them to the specified array.
- *
- * @param c The class to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Class<?> c, Class<? extends V> ofType, V[] array) {
- var list = findAll(c, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified constructor
and appends them to the specified array.
- *
- * @param c The constructor to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Constructor<?> c, Class<? extends V> ofType, V[]
array) {
- var list = findAll(c, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified field and
appends them to the specified array.
- *
- * @param f The field to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Field f, Class<? extends V> ofType, V[] array) {
- var list = findAll(f, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- /**
- * Finds all values in this map that match the specified method and
appends them to the specified array.
- *
- * @param m The method to test for.
- * @param ofType Only return objects of the specified type.
- * @param array The array to append to.
- * @return The array with matching objects appended.
- */
- public V[] appendAll(Method m, Class<? extends V> ofType, V[] array) {
- var list = findAll(m, ofType);
- if (list.isEmpty())
- return array;
- var newArray = Arrays.copyOf(array, array.length + list.size());
- for (int i = 0; i < list.size(); i++)
- newArray[array.length + i] = list.get(i);
- return newArray;
- }
-
- @Override /* Overridden from Object */
- public String toString() {
- // @formatter:off
- 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-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 ddaa303113..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
@@ -45,7 +45,7 @@ public abstract class DebugEnablement {
*/
public static class Builder {
- ReflectionMap2.Builder<Enablement> mapBuilder;
+ ReflectionMap.Builder<Enablement> mapBuilder;
Enablement defaultEnablement = NEVER;
Predicate<HttpServletRequest> conditional;
BeanCreator<DebugEnablement> creator;
@@ -56,7 +56,7 @@ public abstract class DebugEnablement {
* @param beanStore The bean store to use for creating beans.
*/
protected Builder(BeanStore beanStore) {
- mapBuilder = ReflectionMap2.create(Enablement.class);
+ mapBuilder = ReflectionMap.create(Enablement.class);
defaultEnablement = NEVER;
conditional = x ->
"true".equalsIgnoreCase(x.getHeader("Debug"));
creator =
beanStore.createBean(DebugEnablement.class).type(BasicDebugEnablement.class).builder(Builder.class,
this);
@@ -211,7 +211,7 @@ public abstract class DebugEnablement {
}
private final Enablement defaultEnablement;
- private final ReflectionMap2<Enablement> enablementMap;
+ private final ReflectionMap<Enablement> enablementMap;
private final Predicate<HttpServletRequest> conditionalPredicate;
/**
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 2672a5c4ef..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
@@ -26,11 +26,11 @@ import org.apache.juneau.common.reflect.*;
* <li class='link'><a class="doclink"
href="https://juneau.apache.org/docs/topics/RestServerLoggingAndDebugging">Logging
/ Debugging</a>
* </ul>
*/
-public class DebugEnablementMap extends ReflectionMap2<Enablement> {
+public class DebugEnablementMap extends ReflectionMap<Enablement> {
/**
* Builder class.
*/
- public static class Builder extends ReflectionMap2.Builder<Enablement> {
+ public static class Builder extends ReflectionMap.Builder<Enablement> {
/**
* Constructor.
diff --git
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
index 23ffa281c4..d35df256f0 100644
---
a/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
+++
b/juneau-utest/src/test/java/org/apache/juneau/common/reflect/ReflectionMapTest.java
@@ -32,10 +32,10 @@ class ReflectionMapTest extends TestBase {
}
private static void checkEntries(ReflectionMap<?> m, boolean hasClass,
boolean hasMethods, boolean hasFields, boolean hasConstructors) {
- assertEquals(m.classEntries.length == 0, ! hasClass);
- assertEquals(m.methodEntries.length == 0, ! hasMethods);
- assertEquals(m.fieldEntries.length == 0, ! hasFields);
- assertEquals(m.constructorEntries.length == 0, !
hasConstructors);
+ assertEquals(m.classEntries.size() == 0, ! hasClass);
+ assertEquals(m.methodEntries.size() == 0, ! hasMethods);
+ assertEquals(m.fieldEntries.size() == 0, ! hasFields);
+ assertEquals(m.constructorEntries.size() == 0, !
hasConstructors);
}
//------------------------------------------------------------------------------------------------------------------