You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2026/05/04 13:01:32 UTC

(juneau) branch master updated: refactor: rename simpleVarResolver->bootstrapVarResolver and rootBeanStore->bootstrapBeanStore in RestContext

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 e7fc2d81bf refactor: rename simpleVarResolver->bootstrapVarResolver and rootBeanStore->bootstrapBeanStore in RestContext
e7fc2d81bf is described below

commit e7fc2d81bfa3d65e09e5eb90302340071ff0c913
Author: James Bognar <ja...@jamesbog-ltmjqf2.internal.salesforce.com>
AuthorDate: Mon May 4 09:01:26 2026 -0400

    refactor: rename simpleVarResolver->bootstrapVarResolver and rootBeanStore->bootstrapBeanStore in RestContext
---
 .../java/org/apache/juneau/rest/RestContext.java   | 102 +++++++++++----------
 .../java/org/apache/juneau/rest/RestOpContext.java |   2 +-
 .../apache/juneau/rest/rrpc/RrpcRestOpContext.java |   2 +-
 todo/TODO.md                                       |  26 +++++-
 4 files changed, 78 insertions(+), 54 deletions(-)

diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index a50b3fa25f..1ce6eaab9e 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -151,7 +151,7 @@ public class RestContext extends Context {
 	private static final String PROP_produces = "produces";
 	private static final String PROP_responseProcessors = "responseProcessors";
 	private static final String PROP_restOpArgs = "restOpArgs";
-	private static final String PROP_simpleVarResolver = "simpleVarResolver";
+	private static final String PROP_bootstrapVarResolver = "bootstrapVarResolver";
 	private static final String PROP_staticFiles = "staticFiles";
 	private static final String PROP_swaggerProvider = "swaggerProvider";
 
@@ -216,7 +216,7 @@ public class RestContext extends Context {
 			PROP_defaultRequestAttributes,
 			PROP_defaultRequestHeaders,
 			PROP_defaultResponseHeaders,
-			PROP_simpleVarResolver,
+			PROP_bootstrapVarResolver,
 			"destroyMethods",
 			"endCallMethods",
 			"postCallMethods",
@@ -252,7 +252,7 @@ public class RestContext extends Context {
 
 		private BeanContext.Builder beanContext;
 		private BasicBeanStore beanStore;
-		private BasicBeanStore rootBeanStore;
+		private BasicBeanStore bootstrapBeanStore;
 		private boolean initialized;
 		private final Class<?> resourceClass;
 		private Config config;
@@ -274,7 +274,7 @@ public class RestContext extends Context {
 		private SerializerSet.Builder serializers;
 		private final ServletConfig inner;
 		private String path = null;
-		private VarResolver simpleVarResolver;
+		private VarResolver bootstrapVarResolver;
 
 		/**
 		 * Package-private constructor.
@@ -295,7 +295,7 @@ public class RestContext extends Context {
 			this.parentContext = parentContext;
 
 			if (nn(parentContext))
-				rootBeanStore = parentContext.rootBeanStore;
+				bootstrapBeanStore = parentContext.bootstrapBeanStore;
 		}
 
 		@Override /* Context.Builder is abstract - copy() is not meaningful for the transient RestContext bootstrap state. */
@@ -719,14 +719,14 @@ public class RestContext extends Context {
 				.addBean(ServletContext.class, (nn(inner) ? inner : this).getServletContext());
 			// @formatter:on
 
-			if (rootBeanStore == null) {
-				rootBeanStore = beanStore;
-				beanStore = BasicBeanStore.of(rootBeanStore);
+			if (bootstrapBeanStore == null) {
+				bootstrapBeanStore = beanStore;
+				beanStore = BasicBeanStore.of(bootstrapBeanStore);
 			}
 			var bs = beanStore;
 
 			beanStore.add(BasicBeanStore.class, bs);
-			beanStore.add(VarResolver.class, simpleVarResolver());
+			beanStore.add(VarResolver.class, bootstrapVarResolver());
 			config = beanStore.add(Config.class, createConfig(bs, r, rc));
 
 			var rci = ClassInfo.of(resourceClass);
@@ -756,7 +756,7 @@ public class RestContext extends Context {
 				}
 			});
 
-			var vrs = simpleVarResolver().createSession();
+			var vrs = bootstrapVarResolver().createSession();
 			var work = AnnotationWorkList.of(vrs, rstream(AP.find(rci)).filter(CONTEXT_APPLY_FILTER));
 
 			apply(work);
@@ -1105,16 +1105,16 @@ public class RestContext extends Context {
 		}
 
 		/**
-		 * Returns the root bean store.
+		 * Returns the bootstrap bean store.
 		 *
 		 * <p>
 		 * This is the bean store inherited from the parent resource and does not include
 		 * any beans added by this class.
 		 *
-		 * @return The root bean store.
+		 * @return The bootstrap bean store.
 		 */
-		public BasicBeanStore rootBeanStore() {
-			return rootBeanStore;
+		public BasicBeanStore bootstrapBeanStore() {
+			return bootstrapBeanStore;
 		}
 
 		/**
@@ -1149,32 +1149,32 @@ public class RestContext extends Context {
 		}
 
 		/**
-		 * Returns the simple (bootstrap-time) variable resolver for this REST context.
+		 * Returns the bootstrap (pre-runtime) variable resolver for this REST context.
 		 *
 		 * <p>
-		 * The simple resolver is used during context construction to resolve SVL variables in annotation attribute values
+		 * The bootstrap resolver is used during context construction to resolve SVL variables in annotation attribute values
 		 * (e.g. <c>@Rest(messages=...)</c>, <c>@Rest(config=...)</c>) before the runtime {@link VarResolver} — which has
 		 * {@link Messages} and {@link Config} beans wired in — is available. It exposes the same {@link Var} catalog as
 		 * the runtime resolver, but {@link LocalizationVar} and {@link ConfigVar} resolve to empty strings because their
 		 * backing beans haven't been built yet.
 		 *
 		 * <p>
-		 * To override the simple resolver, declare a named {@link RestInject @RestInject} static method on the resource
+		 * To override the bootstrap resolver, declare a named {@link RestInject @RestInject} static method on the resource
 		 * class:
 		 * <p class='bjava'>
-		 * 	<ja>@RestInject</ja>(name=<js>"simpleVarResolver"</js>) <jk>public static</jk> VarResolver mySimpleResolver(<i>&lt;args&gt;</i>) {...}
+		 * 	<ja>@RestInject</ja>(name=<js>"bootstrapVarResolver"</js>) <jk>public static</jk> VarResolver myBootstrapResolver(<i>&lt;args&gt;</i>) {...}
 		 * </p>
 		 *
 		 * <h5 class='section'>See Also:</h5><ul>
 		 * 	<li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a>
 		 * </ul>
 		 *
-		 * @return The simple (bootstrap-time) variable resolver. Cached on first call.
+		 * @return The bootstrap (pre-runtime) variable resolver. Cached on first call.
 		 */
-		public VarResolver simpleVarResolver() {
-			if (simpleVarResolver == null)
-				simpleVarResolver = createSimpleVarResolver(beanStore, resource, resourceClass);
-			return simpleVarResolver;
+		public VarResolver bootstrapVarResolver() {
+			if (bootstrapVarResolver == null)
+				bootstrapVarResolver = createBootstrapVarResolver(beanStore, resource, resourceClass);
+			return bootstrapVarResolver;
 		}
 
 		private static void runInitHooks(BasicBeanStore beanStore, Supplier<?> resource) throws ServletException {
@@ -1253,7 +1253,7 @@ public class RestContext extends Context {
 			var v = Value.of(
 				BasicBeanStore
 					.create()
-					.parent(rootBeanStore())
+					.parent(bootstrapBeanStore())
 				);
 			// @formatter:on
 
@@ -1899,7 +1899,7 @@ public class RestContext extends Context {
 						// We override the CallMethod.invoke() method to insert our logic.
 						if ("RRPC".equals(httpMethod)) {
 
-							// `RestOpContext.create(method, context).beanStore(restContext.getRootBeanStore()).type(RrpcRestOpContext.class).build()` →
+							// `RestOpContext.create(method, context).beanStore(restContext.getBootstrapBeanStore()).type(RrpcRestOpContext.class).build()` →
 							// `new RrpcRestOpContext(method, context)`. The bean-store override (root, not the
 							// resource-layered store) is preserved verbatim inside the new 2-arg ctor on
 							// `RrpcRestOpContext`. The `.dotAll()` flag was removed per TODO-16 Decision #17 —
@@ -1978,13 +1978,13 @@ public class RestContext extends Context {
 		}
 
 		/**
-		 * Creates the simple (bootstrap-time) variable resolver.
+		 * Creates the bootstrap (pre-runtime) variable resolver.
 		 *
 		 * <p>
 		 * Builds the same {@link Var} catalog as the runtime resolver but without {@link Messages} or {@link Config}
 		 * beans wired in — those depend on settings that are themselves resolved against this resolver, so they're
 		 * added later by {@link RestContext#findVarResolver()}. Override via
-		 * {@link RestInject @RestInject(name="simpleVarResolver")} on a static method.
+		 * {@link RestInject @RestInject(name="bootstrapVarResolver")} on a static method.
 		 *
 		 * <h5 class='section'>See Also:</h5><ul>
 		 * 	<li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerSvlVariables">SVL Variables</a>
@@ -1996,9 +1996,9 @@ public class RestContext extends Context {
 		 * 	The REST servlet/bean instance that this context is defined against.
 		 * @param resourceClass
 		 * 	The REST servlet/bean type that this context is defined against.
-		 * @return The built simple variable resolver.
+		 * @return The built bootstrap variable resolver.
 		 */
-		protected VarResolver createSimpleVarResolver(BasicBeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
+		protected VarResolver createBootstrapVarResolver(BasicBeanStore beanStore, Supplier<?> resource, Class<?> resourceClass) {
 
 			// Default value.
 			// @formatter:off
@@ -2032,11 +2032,11 @@ public class RestContext extends Context {
 			);
 			// @formatter:on
 
-			// Replace with named bean from bean store (PROP_simpleVarResolver).
-			beanStore.getBean(VarResolver.class, PROP_simpleVarResolver).ifPresent(v::set);
+			// Replace with named bean from bean store (PROP_bootstrapVarResolver).
+			beanStore.getBean(VarResolver.class, PROP_bootstrapVarResolver).ifPresent(v::set);
 
-			// Replace with bean from:  @RestInject(name="simpleVarResolver") public [static] VarResolver xxx(<args>)
-			new BeanCreateMethodFinder<>(VarResolver.class, resource.get(), beanStore).find(x -> isRestInjectMethod(x, PROP_simpleVarResolver)).run(v::set);
+			// Replace with bean from:  @RestInject(name="bootstrapVarResolver") public [static] VarResolver xxx(<args>)
+			new BeanCreateMethodFinder<>(VarResolver.class, resource.get(), beanStore).find(x -> isRestInjectMethod(x, PROP_bootstrapVarResolver)).run(v::set);
 
 			return v.get();
 		}
@@ -2101,7 +2101,7 @@ public class RestContext extends Context {
 	protected final AtomicBoolean initialized = new AtomicBoolean(false);
 	protected final BasicHttpException initException;
 	protected final BasicBeanStore beanStore;
-	protected final BasicBeanStore rootBeanStore;
+	protected final BasicBeanStore bootstrapBeanStore;
 	protected final Builder builder;
 	protected final Class<?> resourceClass;
 	protected final ConcurrentHashMap<Locale,Swagger> swaggerCache = new ConcurrentHashMap<>();
@@ -2143,10 +2143,10 @@ public class RestContext extends Context {
 
 	// Bootstrap-time resolver — no Messages, no Config bean. Cached on the builder so that init()
 	// and findMessages()/findConfig() see the same instance during construction.
-	private final Memoizer<VarResolver> simpleVarResolverMemo = memoizer(this::findSimpleVarResolver);
+	private final Memoizer<VarResolver> bootstrapVarResolverMemo = memoizer(this::findBootstrapVarResolver);
 
-	private VarResolver findSimpleVarResolver() {
-		return builder.simpleVarResolver();
+	private VarResolver findBootstrapVarResolver() {
+		return builder.bootstrapVarResolver();
 	}
 
 	private final Memoizer<Messages> messagesMemo = memoizer(this::findMessages);
@@ -2158,7 +2158,7 @@ public class RestContext extends Context {
 		Collections.reverse(anns);
 		// Resolve location strings against the simple resolver — full resolver isn't available yet
 		// (it depends on getMessages()).
-		var vrs = getSimpleVarResolver().createSession();
+		var vrs = getBootstrapVarResolver().createSession();
 		anns.forEach(ai -> ai.getString(PROPERTY_messages).filter(StringUtils::isNotBlank).ifPresent(s -> b.location(vrs.resolve(s))));
 		beanStore.getBean(Messages.class).ifPresent(b::impl);
 		new BeanCreateMethodFinder<>(Messages.class, resource.get(), beanStore).addBean(Messages.Builder.class, b).find(Builder::isRestInjectMethod).run(b::impl);
@@ -2187,13 +2187,13 @@ public class RestContext extends Context {
 	}
 
 	// Runtime resolver — wraps the simple resolver and adds Messages + Config beans.
-	// Depends on getSimpleVarResolver() and getMessages(); pulls the bootstrap Config from the builder
+	// Depends on getBootstrapVarResolver() and getMessages(); pulls the bootstrap Config from the builder
 	// to avoid an infinite recursion with the runtime Config (which wraps the bootstrap Config in a
 	// session backed by *this* resolver).
 	private final Memoizer<VarResolver> varResolverMemo = memoizer(this::findVarResolver);
 
 	private VarResolver findVarResolver() {
-		var b = getSimpleVarResolver().copy()
+		var b = getBootstrapVarResolver().copy()
 			.bean(Messages.class, getMessages())
 			.bean(Config.class, builder.config());
 		beanStore.getBean(VarResolver.class).ifPresent(b::impl);
@@ -2485,7 +2485,7 @@ public class RestContext extends Context {
 			parentContext = builder.parentContext;
 			resource = builder.resource;
 			resourceClass = builder.resourceClass;
-			rootBeanStore = builder.rootBeanStore();
+			bootstrapBeanStore = builder.bootstrapBeanStore();
 
 			BasicBeanStore bs = beanStore = builder.beanStore();
 			// @formatter:off
@@ -3375,11 +3375,15 @@ public class RestContext extends Context {
 	public RestOperations getRestOperations() { return restOperations; }
 
 	/**
-	 * Returns the root bean store for this context.
+	 * Returns the bootstrap bean store for this context.
 	 *
-	 * @return The root bean store for this context.
+	 * <p>
+	 * This is the bean store inherited from the parent resource and does not include
+	 * any beans added by this class.
+	 *
+	 * @return The bootstrap bean store for this context.
 	 */
-	public BasicBeanStore getRootBeanStore() { return rootBeanStore; }
+	public BasicBeanStore getBootstrapBeanStore() { return bootstrapBeanStore; }
 
 	/**
 	 * Returns the serializers associated with this context.
@@ -3566,17 +3570,17 @@ public class RestContext extends Context {
 	public VarResolver getVarResolver() { return varResolverMemo.get(); }
 
 	/**
-	 * Returns the simple (bootstrap-time) variable resolver used during context construction.
+	 * Returns the bootstrap (pre-runtime) variable resolver used during context construction.
 	 *
 	 * <p>
-	 * The simple resolver has the same {@link Var} catalog as {@link #getVarResolver()} but does not have
+	 * The bootstrap resolver has the same {@link Var} catalog as {@link #getVarResolver()} but does not have
 	 * {@link Messages} or {@link Config} beans wired in — it is used to resolve annotation attribute values
 	 * (e.g. <c>@Rest(messages=...)</c>) before those beans are built. Override via
-	 * {@link RestInject @RestInject(name="simpleVarResolver")} on a static method of the resource class.
+	 * {@link RestInject @RestInject(name="bootstrapVarResolver")} on a static method of the resource class.
 	 *
-	 * @return The simple var resolver in use by this resource.
+	 * @return The bootstrap var resolver in use by this resource.
 	 */
-	public VarResolver getSimpleVarResolver() { return simpleVarResolverMemo.get(); }
+	public VarResolver getBootstrapVarResolver() { return bootstrapVarResolverMemo.get(); }
 
 	/**
 	 * Returns whether it's safe to pass the HTTP content as a <js>"content"</js> GET parameter.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index 26e1f52689..83624649c6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -1295,7 +1295,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 			mi = MethodInfo.of(method).accessible();
 
 			// @formatter:off
-			var bs = BasicBeanStore.of(context.getRootBeanStore())
+			var bs = BasicBeanStore.of(context.getBootstrapBeanStore())
 				.addBean(RestOpContext.class, this)
 				.addBean(Method.class, method)
 				.addBean(AnnotationWorkList.class, builder.getApplied());
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/rrpc/RrpcRestOpContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/rrpc/RrpcRestOpContext.java
index f250bf51f3..1c25e006f9 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/rrpc/RrpcRestOpContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/rrpc/RrpcRestOpContext.java
@@ -61,7 +61,7 @@ public class RrpcRestOpContext extends RestOpContext {
 	 * @since 9.5.0
 	 */
 	public RrpcRestOpContext(Method method, RestContext context) throws ServletException {
-		super(method, context, context.getRootBeanStore());
+		super(method, context, context.getBootstrapBeanStore());
 
 		var interfaceClass = getBeanContext().getClassMeta(getJavaMethod().getGenericReturnType());
 		meta = new RrpcInterfaceMeta(interfaceClass.inner(), null);
diff --git a/todo/TODO.md b/todo/TODO.md
index dda5cc8e05..d2161cb692 100644
--- a/todo/TODO.md
+++ b/todo/TODO.md
@@ -1,5 +1,6 @@
 # TODO
 
+
 - [TODO-1] Update REST server API to use new BeanStore2.
 
 - [TODO-2] On RestClient when logging with FULL, calling RestResponse.getContent().asString() causes a stream closed exception.
@@ -8,7 +9,27 @@
 
 - [TODO-4] Duration.ofDays(7) serialized in hours?
 
-- [TODO-17] Audit 9.2.x changes (juneau-docs release notes 9.2.0 / 9.2.1 + git history since 9.1.0) for breaking changes and populate the v9.5 Migration Guide at juneau-docs/pages/topics/23.01.V9.5-migration-guide.md with Old→New rows for each. Focus on removed APIs, renamed annotations/classes/methods, changed default behaviors, and any annotation-attribute semantics changes.
+- [TODO-6] Add an `ai` / `shortDescription` field to `@Schema` (and related annotations) for concise LLM/AI-consumption descriptions that stay under token budgets. See `todo/TODO-6-ai-short-description.md`.
+
+- [TODO-7] Decouple `juneau-rest-common` from `juneau-marshall` by breaking the compile dependency so REST annotations and beans can be used without pulling in the full serialization stack. See `todo/TODO-7-decouple-rest-common-from-marshall.md`.
+
+- [TODO-8] Add typed `JsonSchema` bean output to `JsonSchemaGenerator` (currently returns only `JsonMap`). Requires filling gaps in the `JsonSchema` bean and adding a bridge class in `juneau-bean-jsonschema`. See `todo/TODO-8-jsonschema-bean-generation.md`.
+
+- [TODO-9] Fix remaining skipped Markdown round-trip test cases (tables, nested structures, edge cases). See `todo/TODO-9-markdown-remaining-issues.md`.
+
+- [TODO-10] Move `org.apache.juneau.http.annotation` from `juneau-marshall` into `juneau-rest-common` (already done for the annotation classes — plan tracks remaining follow-on cleanup). See `todo/TODO-10-move-http-annotation-to-rest-common.md`.
+
+- [TODO-11] Next-generation RestClient transport abstraction: decouple `RestClient` from Apache HttpClient 4.5 so any HTTP transport can be plugged in. See `todo/TODO-11-restclient2-transport-abstraction.md`.
+
+- [TODO-12] Schema validation mode for parsers and serializers: wire `@Schema` validation into the bean property get/set lifecycle gated by a new `validateSchema` flag on `BeanContext`. See `todo/TODO-12-schema-validation.md`.
+
+- [TODO-13] Convert Juneau system properties to the `Settings` class in `juneau-commons`. See `todo/TODO-13-system-properties-to-settings-conversion.md`.
+
+- [TODO-14] Move SVL (`org.apache.juneau.svl`) from `juneau-marshall` into `juneau-commons` so `VarResolver` can be used without the full marshall dependency. See `todo/TODO-14-move-svl-to-commons.md`.
+
+- [TODO-15] Replace `BasicBeanStore` / `BeanCreator` with the v2 equivalents in `juneau-commons.inject`, then drop the `2` suffix and remove the legacy classes. See `todo/TODO-15-replace-basicbeanstore-with-v2.md`.
+
+- [TODO-17] Audit 9.2.x changes (juneau-docs release notes 9.2.0 / 9.5.0 + git history since 9.1.0) for breaking changes and populate the v9.5 Migration Guide at juneau-docs/pages/topics/23.01.V9.5-migration-guide.md with Old→New rows for each. Focus on removed APIs, renamed annotations/classes/methods, changed default behaviors, and any annotation-attribute semantics changes.
 
 - [TODO-18] Investigate possible useful features to add to juneau-rest-server.
 
@@ -16,9 +37,8 @@
 
 - [TODO-20] Rethink how debugging works in RestServlet.  Can we come up with a simpler system?
 
-- [TODO-22] In RestServlet, consider renaming simpleVarResolver->bootstrapVarResolver and rootBeanStore->bootstrapBeanStore.
+- [TODO-21] Rename and relocate bean/inject annotations: reduce confusion with Spring naming, align annotation vocabulary with what each actually does, and move resource/store contribution annotations into `org.apache.juneau.commons.inject`. See `todo/TODO-21-bean-annotations-inject-package.md`.
 
 - [TODO-23] New feature support in org.apache.juneau.commons.inject — roadmap for a simplified inject API (not a Spring replacement). See `todo/TODO-23-commons-inject-framework-roadmap.md`.
 
 - [TODO-24] JSR-330 alignment (no `jakarta.inject-api` dependency) + selective Spring-lite features for `commons.inject`. See `todo/TODO-24-jsr330-and-spring-lite-support.md`.
-