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 fd2d1d03a5 Utility class modernization
fd2d1d03a5 is described below
commit fd2d1d03a51fded9fcfcb5548b57b3314407deae
Author: James Bognar <[email protected]>
AuthorDate: Fri Nov 7 18:17:27 2025 -0500
Utility class modernization
---
CLAUDE.md | 64 +-
.../juneau/common/reflect/AnnotationProvider.java | 4 +-
.../juneau/common/reflect/ReflectionMap2.java | 763 ---------------------
.../apache/juneau/rest/debug/DebugEnablement.java | 6 +-
.../juneau/rest/debug/DebugEnablementMap.java | 4 +-
scripts/revert-staged.py | 75 ++
scripts/revert-unstaged.py | 68 ++
7 files changed, 188 insertions(+), 796 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index f9887eff2c..3220dc1ab6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -181,46 +181,58 @@ public class ClassInfo {
#### Git Operations and Reverts
When working with git operations, especially reverting changes:
-1. **Always revert to staged version only** - Use `git restore --source=INDEX`
to revert unstaged changes back to the staged (tested) version:
- - ✅ CORRECT: `git restore --source=INDEX path/to/specific/File.java`
- - ❌ WRONG: `git checkout -- path/to/file` (reverts to HEAD, loses staged
changes)
- - ❌ WRONG: `git restore path/to/file` (reverts to HEAD, loses staged
changes)
-
-2. **Always revert one file at a time** - Never use broad wildcards or
multiple file paths:
- - ✅ CORRECT: `git restore --source=INDEX path/to/specific/File.java`
- - ❌ WRONG: `git restore --source=INDEX .` (reverts everything)
- - ❌ WRONG: `git restore --source=INDEX module1/ module2/` (reverts multiple
locations)
-
-3. **Why this matters:**
+1. **Use helper scripts for reverting** - Always use the provided Python
scripts instead of git commands directly:
+ - ✅ CORRECT: `./scripts/revert-unstaged.py path/to/specific/File.java`
(reverts unstaged to staged)
+ - ✅ CORRECT: `./scripts/revert-staged.py path/to/specific/File.java`
(reverts to HEAD, discards all changes)
+ - ❌ WRONG: Using `git restore`, `git checkout`, or any git commands directly
+
+2. **Revert Unstaged Changes Script** - `./scripts/revert-unstaged.py`
+ - Reverts working directory changes back to the staged (INDEX) version
+ - Preserves staged changes that have been tested
+ - Use this when you have staged changes you want to keep
+ - Command: `git restore --source=INDEX <file>`
+
+3. **Revert Staged Changes Script** - `./scripts/revert-staged.py`
+ - Reverts both staged AND unstaged changes back to HEAD (last commit)
+ - ⚠️ WARNING: Discards all changes (staged and unstaged)
+ - Use this when you want to completely discard all changes to a file
+ - Command: `git restore --source=HEAD <file>`
+
+4. **Always revert one file at a time** - Never use broad wildcards or
multiple file paths:
+ - ✅ CORRECT: `./scripts/revert-unstaged.py path/to/specific/File.java`
+ - ❌ WRONG: Reverting multiple files or using wildcards
+
+5. **Why this matters:**
- **Preserves staged changes**: Staged changes have been tested and should
not be lost
- - **Surgical precision**: Only reverts the specific problematic file's
unstaged changes
+ - **Surgical precision**: Only reverts the specific problematic file's
changes
- **Safe recovery**: If a file is staged, it means it was working at that
point
- **Prevents data loss**: Won't accidentally revert good changes along with
bad ones
+ - **User-friendly**: Scripts provide clear feedback and prevent common
mistakes
-4. **Proper workflow when compilation fails:**
+6. **Proper workflow when compilation fails:**
- Identify the specific file(s) causing the error
- - Revert only that file's unstaged changes: `git restore --source=INDEX
path/to/ProblematicFile.java`
+ - Revert only that file's unstaged changes: `./scripts/revert-unstaged.py
path/to/ProblematicFile.java`
- Verify the revert fixed the issue (back to staged/tested version)
- Then address that specific file's changes separately
**Examples:**
```bash
-# WRONG - Reverts all unstaged changes everywhere
-git restore --source=INDEX .
+# CORRECT - Revert unstaged changes only (preserves staged)
+./scripts/revert-unstaged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectSearcher.java
-# WRONG - Reverts to HEAD, losing staged changes
-git checkout -- path/to/file
-git restore path/to/file
+# CORRECT - Revert all changes back to HEAD (discards everything)
+./scripts/revert-staged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectSearcher.java
-# CORRECT - Revert specific file's unstaged changes to staged version
-git restore --source=INDEX
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/objecttools/ObjectSearcher.java
+# WRONG - Don't use git commands directly
+git restore --source=INDEX path/to/file
+git checkout -- path/to/file
```
-**Understanding git restore --source=INDEX:**
-- `INDEX` refers to the staging area (where `git add` puts files)
-- This command reverts working directory changes back to what's staged
-- Staged changes remain intact and are not affected
-- If a file isn't staged, this command does nothing (which is safe)
+**Understanding the scripts:**
+- `revert-unstaged.py`: Uses `git restore --source=INDEX` to revert to staged
version
+- `revert-staged.py`: Uses `git restore --source=HEAD` to revert to last commit
+- Both scripts handle one file at a time for safety
+- Both provide clear feedback about what they're doing
### 2. Testing Standards
- Ensure comprehensive test coverage for all changes
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 f0a9f12824..eb09b86a4a 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
@@ -211,7 +211,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;
@@ -409,7 +409,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/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/scripts/revert-staged.py b/scripts/revert-staged.py
new file mode 100755
index 0000000000..23692f3004
--- /dev/null
+++ b/scripts/revert-staged.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+#
***************************************************************************************************************************
+# * 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.
+#
***************************************************************************************************************************
+"""
+Revert staged changes back to HEAD (last commit).
+
+This script reverts both staged AND unstaged changes back to the last
committed version.
+⚠️ WARNING: This will discard all changes (staged and unstaged) for the
specified file.
+
+Usage:
+ ./scripts/revert-staged.py <file_path>
+
+Example:
+ ./scripts/revert-staged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+"""
+
+import sys
+import subprocess
+from pathlib import Path
+
+def main():
+ if len(sys.argv) != 2:
+ print("Error: Exactly one file path argument required")
+ print()
+ print("Usage: ./scripts/revert-staged.py <file_path>")
+ print()
+ print("Example:")
+ print(" ./scripts/revert-staged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java")
+ sys.exit(1)
+
+ file_path = sys.argv[1]
+
+ # Verify file exists or is tracked by git
+ try:
+ subprocess.run(
+ ["git", "ls-files", "--error-unmatch", file_path],
+ check=True,
+ capture_output=True,
+ text=True
+ )
+ except subprocess.CalledProcessError:
+ print(f"Error: File not tracked by git: {file_path}")
+ sys.exit(1)
+
+ print(f"⚠️ WARNING: This will discard ALL changes (staged and unstaged)
for: {file_path}")
+ print(f"Command: git restore --source=HEAD {file_path}")
+ print()
+
+ try:
+ result = subprocess.run(
+ ["git", "restore", "--source=HEAD", file_path],
+ check=True,
+ capture_output=True,
+ text=True
+ )
+ print(f"✅ Successfully reverted to HEAD for: {file_path}")
+ print(" (All staged and unstaged changes discarded)")
+ return 0
+ except subprocess.CalledProcessError as e:
+ print(f"❌ Error reverting file: {e.stderr}")
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
+
diff --git a/scripts/revert-unstaged.py b/scripts/revert-unstaged.py
new file mode 100755
index 0000000000..3bf6a26a5f
--- /dev/null
+++ b/scripts/revert-unstaged.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
***************************************************************************************************************************
+# * 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.
+#
***************************************************************************************************************************
+"""
+Revert unstaged changes back to the staged (INDEX) version.
+
+This script safely reverts working directory changes back to what's in the
staging area,
+preserving any staged changes that have been tested.
+
+Usage:
+ ./scripts/revert-unstaged.py <file_path>
+
+Example:
+ ./scripts/revert-unstaged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+"""
+
+import sys
+import subprocess
+from pathlib import Path
+
+def main():
+ if len(sys.argv) != 2:
+ print("Error: Exactly one file path argument required")
+ print()
+ print("Usage: ./scripts/revert-unstaged.py <file_path>")
+ print()
+ print("Example:")
+ print(" ./scripts/revert-unstaged.py
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java")
+ sys.exit(1)
+
+ file_path = sys.argv[1]
+
+ # Verify file exists
+ if not Path(file_path).exists():
+ print(f"Error: File not found: {file_path}")
+ sys.exit(1)
+
+ print(f"Reverting unstaged changes for: {file_path}")
+ print(f"Command: git restore --source=INDEX {file_path}")
+ print()
+
+ try:
+ result = subprocess.run(
+ ["git", "restore", "--source=INDEX", file_path],
+ check=True,
+ capture_output=True,
+ text=True
+ )
+ print(f"✅ Successfully reverted unstaged changes for: {file_path}")
+ print(" (Staged changes preserved)")
+ return 0
+ except subprocess.CalledProcessError as e:
+ print(f"❌ Error reverting file: {e.stderr}")
+ return 1
+
+if __name__ == "__main__":
+ sys.exit(main())
+