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/06/01 13:19:52 UTC
(juneau) branch master updated: Implement TODO-145 builder-deferred REST class-family architecture
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 40a74b4f94 Implement TODO-145 builder-deferred REST class-family architecture
40a74b4f94 is described below
commit 40a74b4f945238fa6d35946fa63380d0e8ec936d
Author: James Bognar <ja...@apache.org>
AuthorDate: Mon Jun 1 09:19:45 2026 -0400
Implement TODO-145 builder-deferred REST class-family architecture
- Rename RestObject -> RestResource (+ BasicRestObject[Group] -> BasicRestResource[Group]) and introduce the opt-in RestMixin base.
- Add per-capability flavor classes (Servlet/Resource/Mixin) for StaticFiles, Version, Admin, Health, the 4 view engines, and Favicon (annotation-configured; builder surface deferred to TODO-143).
- Split BasicRestOperations into single-responsibility op-mixins (error/favicon/htdoc/stats).
- Drop the "Basic" prefix from capability classes (kept for convenience bundles); BasicViewServlet -> ViewServlet.
- Remove RestRequest.getStaticFiles() (repoint FileVar/Widget/StaticFilesMixin; keep RestContext.getStaticFiles()).
- Planning docs: TODO-145 refinements, new TODO-146 (mixin host-RestContext access), TODO.md/TODO-143 updates.
---
.../juneau/commons/inject/ValueResolver.java | 124 +++++++---
.../rest/springboot/HelloWorldResource.java | 2 +-
.../juneau/examples/rest/HelloWorldResource.java | 2 +-
.../juneau/examples/rest/HtmlBeansResource.java | 2 +-
.../juneau/examples/rest/RequestEchoResource.java | 2 +-
.../juneau/examples/rest/SseDemoResource.java | 2 +-
.../juneau/examples/rest/UtilityBeansResource.java | 2 +-
.../jetty/HealthProbeConfiguration.java | 4 +-
.../springboot/template/HelloWorldResource.java | 2 +-
.../juneau/rest/mock/classic/MockConsole.java | 2 +-
.../rest/config/BasicUniversalJenaConfig.java | 6 +-
.../rest/springboot/BasicSpringRestServlet.java | 62 +++--
.../springboot/BasicSpringRestServletGroup.java | 25 +-
.../springboot/JuneauServletRegistrations.java | 2 +-
...reemarkerResource.java => FreemarkerMixin.java} | 44 ++--
...emarkerServlet.java => FreemarkerResource.java} | 43 ++--
...eemarkerServlet.java => FreemarkerServlet.java} | 26 +-
.../rest/view/freemarker/FreemarkerView.java | 8 +-
.../view/freemarker/FreemarkerViewRenderer.java | 12 +-
.../juneau/rest/view/freemarker/package-info.java | 8 +-
.../jsp/{BasicJspResource.java => JspMixin.java} | 36 +--
.../apache/juneau/rest/view/jsp/JspResource.java | 68 ++++++
.../jsp/{BasicJspServlet.java => JspServlet.java} | 30 +--
.../org/apache/juneau/rest/view/jsp/JspView.java | 6 +-
.../juneau/rest/view/jsp/JspViewRenderer.java | 18 +-
.../apache/juneau/rest/view/jsp/package-info.java | 8 +-
...sicMustacheResource.java => MustacheMixin.java} | 40 +--
...cMustacheServlet.java => MustacheResource.java} | 43 ++--
...icMustacheServlet.java => MustacheServlet.java} | 26 +-
.../juneau/rest/view/mustache/MustacheView.java | 6 +-
.../rest/view/mustache/MustacheViewRenderer.java | 12 +-
.../juneau/rest/view/mustache/package-info.java | 8 +-
...cThymeleafResource.java => ThymeleafMixin.java} | 36 +--
...hymeleafServlet.java => ThymeleafResource.java} | 43 ++--
...ThymeleafServlet.java => ThymeleafServlet.java} | 26 +-
.../juneau/rest/view/thymeleaf/ThymeleafView.java | 4 +-
.../rest/view/thymeleaf/ThymeleafViewRenderer.java | 12 +-
.../juneau/rest/view/thymeleaf/package-info.java | 8 +-
.../java/org/apache/juneau/rest/RestContext.java | 8 +-
.../java/org/apache/juneau/rest/RestRequest.java | 11 -
.../org/apache/juneau/rest/annotation/Rest.java | 5 +-
.../rest/beans/ChildResourceDescriptions.java | 3 +-
.../juneau/rest/config/BasicJson5Config.java | 2 +-
.../apache/juneau/rest/config/BasicJsonConfig.java | 2 +-
.../juneau/rest/config/BasicJsonHtmlConfig.java | 2 +-
.../juneau/rest/config/BasicOpenApiConfig.java | 2 +-
.../juneau/rest/config/BasicUniversalConfig.java | 6 +-
...BasicFaviconResource.java => FaviconMixin.java} | 50 ++--
.../juneau/rest/convention/FaviconResource.java | 74 ++++++
.../juneau/rest/convention/FaviconServlet.java | 86 +++++++
.../{BasicSeoResource.java => SeoMixin.java} | 40 +--
...BasicVersionResource.java => VersionMixin.java} | 58 ++---
...sicVersionServlet.java => VersionResource.java} | 45 ++--
...asicVersionServlet.java => VersionServlet.java} | 22 +-
...cWellKnownResource.java => WellKnownMixin.java} | 38 +--
.../juneau/rest/convention/package-info.java | 26 +-
...BasicOpenApiResource.java => OpenApiMixin.java} | 14 +-
.../{BasicRedocResource.java => RedocMixin.java} | 20 +-
...BasicSwaggerResource.java => SwaggerMixin.java} | 18 +-
...cSwaggerUiResource.java => SwaggerUiMixin.java} | 22 +-
.../org/apache/juneau/rest/docs/package-info.java | 26 +-
.../apache/juneau/rest/guard/RateLimitGuard.java | 2 +-
...icHealthResource.java => HealthAggregator.java} | 88 ++++---
.../org/apache/juneau/rest/health/HealthMixin.java | 85 +++++++
.../apache/juneau/rest/health/HealthResource.java | 87 +++++++
.../apache/juneau/rest/health/HealthServlet.java | 93 +++++++
.../{BasicAdminResource.java => AdminMixin.java} | 30 +--
.../{BasicAdminServlet.java => AdminResource.java} | 56 ++---
.../{BasicAdminServlet.java => AdminServlet.java} | 22 +-
.../ops/{BasicEchoResource.java => EchoMixin.java} | 30 +--
.../org/apache/juneau/rest/ops/ErrorMixin.java | 56 +++++
.../org/apache/juneau/rest/ops/HtdocMixin.java | 67 +++++
...outeIndexResource.java => RouteIndexMixin.java} | 16 +-
.../org/apache/juneau/rest/ops/StatsMixin.java | 64 +++++
.../org/apache/juneau/rest/ops/package-info.java | 20 +-
.../juneau/rest/servlet/BasicGroupOperations.java | 66 -----
.../juneau/rest/servlet/BasicRestOperations.java | 162 -------------
...BasicRestObject.java => BasicRestResource.java} | 59 +++--
...bjectGroup.java => BasicRestResourceGroup.java} | 23 +-
.../juneau/rest/servlet/BasicRestServlet.java | 65 +++--
.../juneau/rest/servlet/BasicRestServletGroup.java | 23 +-
.../org/apache/juneau/rest/servlet/RestMixin.java | 58 +++++
.../servlet/{RestObject.java => RestResource.java} | 2 +-
...ticFilesResource.java => StaticFilesMixin.java} | 14 +-
...cFilesServlet.java => StaticFilesResource.java} | 48 ++--
...icFilesServlet.java => StaticFilesServlet.java} | 22 +-
.../java/org/apache/juneau/rest/vars/FileVar.java | 4 +-
.../juneau/rest/view/RawTemplateDispatcher.java | 8 +-
.../java/org/apache/juneau/rest/view/View.java | 2 +-
.../org/apache/juneau/rest/view/ViewResource.java | 81 +++++++
.../{BasicViewServlet.java => ViewServlet.java} | 2 +-
.../java/org/apache/juneau/rest/widget/Widget.java | 2 +-
.../inject/Value_SupplierTypedFieldType_Test.java | 269 +++++++++++++++++++++
.../utils/FileUtils_ResolveSafely_Test.java | 2 +-
.../http/classic/SerializedHttpEntity_Test.java | 2 +-
.../org/apache/juneau/http/remote/Remote_Test.java | 6 +-
.../org/apache/juneau/rest/NoInherit_Test.java | 22 +-
...RestPathsRuntimeOverride_GetterShapes_Test.java | 2 +-
.../rest/RestPathsRuntimeOverride_Getter_Test.java | 8 +-
.../rest/StandaloneServletPathResolution_Test.java | 20 +-
.../StandaloneServlets_JettyMicroservice_Test.java | 12 +-
.../classic/BasicHttpRequestRetryHandler_Test.java | 2 +-
.../client/classic/RestCallException_Test.java | 2 +-
.../client/classic/RestClient_BasicCalls_Test.java | 2 +-
.../rest/client/classic/RestClient_Body_Test.java | 2 +-
.../classic/RestClient_Config_Context_Test.java | 2 +-
.../RestClient_Config_MarshallingContext_Test.java | 4 +-
.../classic/RestClient_Config_OpenApi_Test.java | 2 +-
.../classic/RestClient_Config_Parser_Test.java | 2 +-
.../classic/RestClient_Config_RestClient_Test.java | 4 +-
.../classic/RestClient_Config_Serializer_Test.java | 2 +-
.../client/classic/RestClient_FormData_Test.java | 2 +-
.../client/classic/RestClient_Headers_Test.java | 2 +-
.../RestClient_Logging_StreamClosed_Test.java | 2 +-
.../client/classic/RestClient_Logging_Test.java | 2 +-
.../client/classic/RestClient_Marshalls_Test.java | 2 +-
.../rest/client/classic/RestClient_Paths_Test.java | 2 +-
.../rest/client/classic/RestClient_Query_Test.java | 2 +-
.../classic/RestClient_Response_Body_Test.java | 2 +-
.../classic/RestClient_Response_Headers_Test.java | 2 +-
.../client/classic/RestClient_Response_Test.java | 6 +-
.../rest/client/classic/RestClient_Test.java | 4 +-
.../convention/BasicConvention_Builders_Test.java | 82 +++----
.../BasicConvention_OpenApiHidden_Test.java | 20 +-
.../BasicConvention_ParentChain_Test.java | 30 +--
...in_Test.java => FaviconMixin_AsMixin_Test.java} | 28 +--
...sMixin_Test.java => SeoMixin_AsMixin_Test.java} | 20 +-
...in_Test.java => VersionMixin_AsMixin_Test.java} | 28 +--
...va => VersionMixin_JettyMicroservice_Test.java} | 16 +-
...Test.java => VersionMixin_Springboot_Test.java} | 20 +-
...java => VersionMixin_SvlPathOverride_Test.java} | 18 +-
...t.java => VersionMixin_ValueAdoption_Test.java} | 10 +-
..._Test.java => WellKnownMixin_AsMixin_Test.java} | 14 +-
.../docs/BasicApiDocs_JettyMicroservice_Test.java | 4 +-
.../rest/docs/BasicApiDocs_ParentChain_Test.java | 31 ++-
.../rest/docs/BasicApiDocs_Springboot_Test.java | 6 +-
.../docs/BasicApiDocs_TransitiveDedupe_Test.java | 39 +--
...in_Test.java => OpenApiMixin_AsMixin_Test.java} | 6 +-
...java => OpenApiMixin_SvlPathOverride_Test.java} | 18 +-
...ixin_Test.java => RedocMixin_AsMixin_Test.java} | 12 +-
...t.java => RedocMixin_SvlPathOverride_Test.java} | 18 +-
...in_Test.java => SwaggerMixin_AsMixin_Test.java} | 6 +-
...Test.java => SwaggerMixin_Standalone_Test.java} | 10 +-
...java => SwaggerMixin_SvlPathOverride_Test.java} | 18 +-
..._Test.java => SwaggerUiMixin_AsMixin_Test.java} | 12 +-
...va => SwaggerUiMixin_SvlPathOverride_Test.java} | 18 +-
...rce_AsMixin_Test.java => HealthMixin_Test.java} | 4 +-
...hResource_Test.java => HealthServlet_Test.java} | 6 +-
.../rest/openapi/OpenApiSchemaReuse_Test.java | 2 +-
.../rest/openapi/OpenApiYamlRoundTrip_Test.java | 2 +-
...ixin_Test.java => AdminMixin_AsMixin_Test.java} | 44 ++--
...t.java => AdminMixin_AuthIntegration_Test.java} | 8 +-
...java => AdminMixin_RateLimitSnapshot_Test.java} | 16 +-
...t.java => AdminMixin_SvlPathOverride_Test.java} | 20 +-
.../rest/ops/BasicOps_OpenApiHidden_Test.java | 10 +-
.../juneau/rest/ops/BasicOps_ParentChain_Test.java | 16 +-
...Mixin_Test.java => EchoMixin_AsMixin_Test.java} | 58 ++---
....java => EchoMixin_JettyMicroservice_Test.java} | 12 +-
...ot_Test.java => EchoMixin_Springboot_Test.java} | 16 +-
...st.java => EchoMixin_SvlPathOverride_Test.java} | 24 +-
...Test.java => RouteIndexMixin_AsMixin_Test.java} | 12 +-
...a => RouteIndexMixin_SvlPathOverride_Test.java} | 18 +-
...JuneauRestServletContainerInitializer_Test.java | 10 +-
.../JuneauRestAutoConfiguration_Test.java | 8 +-
.../JuneauServletRegistrations_Test.java | 2 +-
...tPropertySource_SpringbootIntegration_Test.java | 2 +-
.../SpringEnvironmentPropertySource_Test.java | 4 +-
...est.java => StaticFilesMixin_AsMixin_Test.java} | 8 +-
...ava => StaticFilesMixin_CacheControl_Test.java} | 6 +-
...=> StaticFilesMixin_ImporterOverride_Test.java} | 6 +-
...> StaticFilesMixin_JettyMicroservice_Test.java} | 6 +-
...va => StaticFilesMixin_OpenApiHidden_Test.java} | 16 +-
...> StaticFilesMixin_SpringbootMetaInf_Test.java} | 10 +-
....java => StaticFilesMixin_Springboot_Test.java} | 10 +-
....java => StaticFilesMixin_Standalone_Test.java} | 12 +-
... => StaticFilesMixin_SvlPathOverride_Test.java} | 20 +-
...Test.java => FreemarkerMixin_Builder_Test.java} | 94 +++----
...est.java => FreemarkerMixin_MockRest_Test.java} | 12 +-
...ava => FreemarkerMixin_PathTraversal_Test.java} | 16 +-
...a => FreemarkerMixin_SvlPathOverride_Test.java} | 6 +-
...uilder_Test.java => JspMixin_Builder_Test.java} | 26 +-
...kRest_Test.java => JspMixin_MockRest_Test.java} | 10 +-
..._Test.java => JspMixin_PathTraversal_Test.java} | 10 +-
...est.java => JspMixin_SvlPathOverride_Test.java} | 18 +-
...est_Test.java => JspServlet_MockRest_Test.java} | 8 +-
...r_Test.java => MustacheMixin_Builder_Test.java} | 86 +++----
..._Test.java => MustacheMixin_MockRest_Test.java} | 12 +-
....java => MustacheMixin_PathTraversal_Test.java} | 14 +-
...ava => MustacheMixin_SvlPathOverride_Test.java} | 6 +-
..._Test.java => ThymeleafMixin_Builder_Test.java} | 62 ++---
...Test.java => ThymeleafMixin_MockRest_Test.java} | 12 +-
...java => ThymeleafMixin_PathTraversal_Test.java} | 12 +-
...va => ThymeleafMixin_SvlPathOverride_Test.java} | 6 +-
juneau-utest/test-run-history.tsv | 1 +
194 files changed, 2669 insertions(+), 1756 deletions(-)
diff --git a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/ValueResolver.java b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/ValueResolver.java
index 75dea4ad9a..b9afa41d39 100644
--- a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/ValueResolver.java
+++ b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/inject/ValueResolver.java
@@ -194,9 +194,9 @@ public final class ValueResolver {
}
/**
- * Generic-aware {@code @Value} resolution that honors {@link Supplier}{@code <String>}
+ * Generic-aware {@code @Value} resolution that honors {@link Supplier}{@code <T>}
* field types by returning a re-evaluating, threadsafe Supplier instead of a one-shot
- * resolved value (field-type autodetect — bare {@code String} resolves once, {@code Supplier<String>}
+ * resolved value (field-type autodetect — bare {@code String} resolves once, {@code Supplier<T>}
* re-evaluates per {@code .get()}).
*
* <p>
@@ -205,16 +205,25 @@ public final class ValueResolver {
* <li>{@code Supplier<String>} → returns a {@link Supplier} that re-evaluates the
* compiled template on every {@link Supplier#get()} call, each time against a
* fresh {@link VarResolverSession}. Safe to share across threads.
- * <li>Anything else → delegates to {@link #resolve(String, Class, String)} with the
- * raw target class (preserves existing behavior).
+ * <li>{@code Supplier<T>} for {@code T != String} → returns a {@link Supplier} that, on every
+ * {@link Supplier#get()} call, re-evaluates the template <i>and</i> coerces the resolved
+ * string into {@code T} via the same {@code String -> T} converter machinery that plain
+ * {@code @Value T} uses ({@link Settings#toType(String, Class)}). The coerced value is never
+ * memoized (late-binding contract); coercion failures surface as a {@link RuntimeException}
+ * from {@code .get()} naming the {@code @Value} key and target type. {@code T} is taken from
+ * any type the converter registry can build from a {@code String} (e.g. {@code Integer},
+ * {@code Long}, {@code Boolean}, {@code Duration}, {@code URI}, {@code Path}, enums).
+ * <li>Anything else (including raw {@code Supplier} and {@code Optional<Supplier<T>>}) → delegates
+ * to {@link #resolve(String, Class, String)} with the raw target class (preserves existing
+ * behavior; the {@code Optional<Supplier<T>>} nesting is intentionally not specially handled).
* </ul>
*
* @param expression The {@code @Value} expression. May be {@code null}.
* @param targetType The erased target class (e.g. {@code String.class} or {@code Supplier.class}).
- * @param genericTargetType The declared generic type (e.g. {@code Supplier<String>}). May be
+ * @param genericTargetType The declared generic type (e.g. {@code Supplier<Integer>}). May be
* {@code null}, in which case Supplier-detection is skipped.
* @param siteDescription Human-readable site description for error messages.
- * @return Either a one-shot coerced value, or a {@code Supplier<String>} factory.
+ * @return Either a one-shot coerced value, or a {@code Supplier<T>} factory.
*/
public static Object resolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription) {
return resolve(expression, targetType, genericTargetType, siteDescription, null);
@@ -226,7 +235,7 @@ public final class ValueResolver {
*
* <p>
* The {@code beanStore} reference is captured (not snapshotted) by the returned
- * {@code Supplier<String>} when the declared field/parameter type is {@code Supplier<String>},
+ * {@code Supplier<T>} when the declared field/parameter type is {@code Supplier<...>},
* so re-evaluating reads always see the current state of {@code beanStore.getBeansOfType(PropertySource.class)}.
*
* @param expression The {@code @Value} expression. May be {@code null}.
@@ -235,37 +244,65 @@ public final class ValueResolver {
* @param siteDescription Human-readable site description for error messages.
* @param beanStore Caller-scoped {@link BeanStore} consulted for {@link PropertySource} beans.
* May be {@code null}.
- * @return Either a one-shot coerced value, or a {@code Supplier<String>} factory.
+ * @return Either a one-shot coerced value, or a {@code Supplier<T>} factory.
*/
public static Object resolve(String expression, Class<?> targetType, Type genericTargetType, String siteDescription,
BeanStore beanStore) {
- if (isSupplierOfString(targetType, genericTargetType)) {
- if (expression == null)
- return (Supplier<String>) () -> null;
- var template = getCompiledTemplate(expression);
- // Literal templates fast-path: capture the resolved string once and hand back a
- // constant Supplier. Saves a per-.get() session allocation when the expression
- // has no variables (e.g. @Value("literal") Supplier<String>).
- if (template.isLiteral()) {
- var literal = template.resolve(VarResolver.DEFAULT.createSession());
- return (Supplier<String>) () -> literal;
- }
- if (beanStore == null)
- return template.asSupplierWithFreshSessions(VarResolver.DEFAULT);
- // Capture the BeanStore by-reference so re-evaluating reads see the current state of
- // its PropertySource-typed beans (matches the "by-reference, not snapshot" contract).
- final BeanStore scope = beanStore;
- return (Supplier<String>) () -> {
- var s = VarResolver.DEFAULT.createSession();
- var sources = scopedSources(scope);
- if (sources != null)
- s.bean(PropertySource[].class, sources);
- return template.resolve(s);
- };
+ var elementType = supplierElementType(targetType, genericTargetType);
+ if (elementType != null) {
+ // Build the re-evaluating string Supplier once. This is the same factory the bare
+ // Supplier<String> path has always used.
+ var stringSupplier = buildStringSupplier(expression, beanStore);
+ if (elementType == String.class)
+ return stringSupplier;
+ // Supplier<T> for T != String: coerce per .get() using the same String -> T converter
+ // machinery that plain @Value T uses (resolveCoerce -> Settings.toType). Per the
+ // late-binding contract, the string is re-resolved AND re-coerced on every .get() — the
+ // coerced value is never memoized. Only the converter lookup is cached (Settings.toType
+ // memoizes the discovered String -> T function per type in its toTypeFunctions registry,
+ // so each .get() pays the coercion but not the reflective converter discovery). A coercion
+ // failure surfaces as a BeanCreationException (a RuntimeException) from .get(), naming the
+ // @Value expression and the target type.
+ final Class<?> et = elementType;
+ return (Supplier<Object>) () -> resolveCoerce(stringSupplier.get(), et, expression, siteDescription);
}
return resolve(expression, targetType, siteDescription, beanStore);
}
+ /**
+ * Builds the re-evaluating {@code Supplier<String>} used by the {@code @Value Supplier<...>}
+ * autodetect path. Each {@link Supplier#get()} re-resolves the compiled template against a fresh
+ * {@link VarResolverSession}, so live config changes are reflected (the late-binding contract).
+ *
+ * @param expression The {@code @Value} expression. May be {@code null}.
+ * @param beanStore Caller-scoped {@link BeanStore} consulted for {@link PropertySource} beans. May be {@code null}.
+ * @return A threadsafe, re-evaluating {@code Supplier<String>}.
+ */
+ private static Supplier<String> buildStringSupplier(String expression, BeanStore beanStore) {
+ if (expression == null)
+ return () -> null;
+ var template = getCompiledTemplate(expression);
+ // Literal templates fast-path: capture the resolved string once and hand back a
+ // constant Supplier. Saves a per-.get() session allocation when the expression
+ // has no variables (e.g. @Value("literal") Supplier<String>).
+ if (template.isLiteral()) {
+ var literal = template.resolve(VarResolver.DEFAULT.createSession());
+ return () -> literal;
+ }
+ if (beanStore == null)
+ return template.asSupplierWithFreshSessions(VarResolver.DEFAULT);
+ // Capture the BeanStore by-reference so re-evaluating reads see the current state of
+ // its PropertySource-typed beans (matches the "by-reference, not snapshot" contract).
+ final BeanStore scope = beanStore;
+ return () -> {
+ var s = VarResolver.DEFAULT.createSession();
+ var sources = scopedSources(scope);
+ if (sources != null)
+ s.bean(PropertySource[].class, sources);
+ return template.resolve(s);
+ };
+ }
+
/**
* Returns the caller-scoped {@link PropertySource} array for the supplied {@link BeanStore},
* or {@code null} if the store has no {@code PropertySource}-typed beans (matching the
@@ -286,14 +323,29 @@ public final class ValueResolver {
return map.values().toArray(new PropertySource[0]);
}
- /** Returns {@code true} if the declared field/parameter type is exactly {@code Supplier<String>}. */
- private static boolean isSupplierOfString(Class<?> targetType, Type genericTargetType) {
+ /**
+ * Returns the {@code T} element class of a declared {@code Supplier<T>} injection site, or
+ * {@code null} if the declared type is not a coercible {@code Supplier<T>}.
+ *
+ * <p>
+ * Returns {@code null} (i.e. "not a typed Supplier site, fall through to one-shot resolution")
+ * for raw {@code Supplier}, non-{@code Supplier} parameterized types such as
+ * {@code Optional<Supplier<T>>} (whose raw type is {@code Optional}, not {@code Supplier} — the
+ * nesting is intentionally not specially handled), and type arguments that are not a concrete
+ * {@link Class} (wildcards / type variables). {@code Supplier<String>} returns {@code String.class},
+ * which the caller treats as the pre-existing pass-through behavior.
+ */
+ private static Class<?> supplierElementType(Class<?> targetType, Type genericTargetType) {
if (targetType != Supplier.class)
- return false;
+ return null;
if (!(genericTargetType instanceof ParameterizedType pt))
- return false;
+ return null;
+ if (pt.getRawType() != Supplier.class)
+ return null;
var args = pt.getActualTypeArguments();
- return args.length == 1 && args[0] == String.class;
+ if (args.length != 1)
+ return null;
+ return args[0] instanceof Class<?> c ? c : null;
}
private static Object resolveCoerce(String resolved, Class<?> targetType, String expression, String siteDescription) {
diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/HelloWorldResource.java b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/HelloWorldResource.java
index 93b1292063..727a1380c1 100644
--- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/HelloWorldResource.java
+++ b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/HelloWorldResource.java
@@ -42,7 +42,7 @@ import org.springframework.beans.factory.annotation.*;
"</div>"
}
)
-public class HelloWorldResource extends BasicRestObject {
+public class HelloWorldResource extends BasicRestResource {
@Autowired
private HelloWorldMessageProvider messageProvider;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
index 188c3b2ec1..0f84ce6f66 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HelloWorldResource.java
@@ -37,7 +37,7 @@ import org.apache.juneau.rest.servlet.*;
"</div>"
}
)
-public class HelloWorldResource extends BasicRestObject {
+public class HelloWorldResource extends BasicRestResource {
/**
* [HTTP GET /helloworld]
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HtmlBeansResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HtmlBeansResource.java
index 94f96e67eb..743edab595 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HtmlBeansResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/HtmlBeansResource.java
@@ -56,7 +56,7 @@ import org.apache.juneau.rest.widget.*;
},
asideFloat="RIGHT"
)
-public class HtmlBeansResource extends BasicRestObject {
+public class HtmlBeansResource extends BasicRestResource {
@SuppressWarnings("unused")
private static final long serialVersionUID = 1L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
index 6ffb9006c7..21eb349774 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RequestEchoResource.java
@@ -73,7 +73,7 @@ import org.apache.juneau.commons.bean.*;
@BeanTypeApply(on="HttpServletRequest",value=@BeanType(interfaceClass=HttpServletRequest.class))
@BeanTypeApply(on="HttpSession",value=@BeanType(interfaceClass=HttpSession.class))
@BeanTypeApply(on="ServletContext",value=@BeanType(interfaceClass=ServletContext.class))
-public class RequestEchoResource extends BasicRestObject {
+public class RequestEchoResource extends BasicRestResource {
/**
* [HTTP GET /echo/*]
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SseDemoResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SseDemoResource.java
index 093211dfe7..00332b10d2 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SseDemoResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SseDemoResource.java
@@ -54,7 +54,7 @@ import org.apache.juneau.sse.*;
title = "SSE demo",
description = "Emits a stream of Server-Sent Events with a short delay between events."
)
-public class SseDemoResource extends BasicRestObject {
+public class SseDemoResource extends BasicRestResource {
private static final int EVENT_COUNT = 10;
private static final long SLEEP_MILLIS = 500L;
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
index 067b6dabde..62c2453dd0 100644
--- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java
@@ -54,7 +54,7 @@ import org.apache.juneau.commons.bean.*;
},
asideFloat="RIGHT"
)
-public class UtilityBeansResource extends BasicRestObject {
+public class UtilityBeansResource extends BasicRestResource {
/**
* Sample address bean used for demonstrating utility bean functionality.
diff --git a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/HealthProbeConfiguration.java b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/HealthProbeConfiguration.java
index 101290b38c..612f0c9d51 100644
--- a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/HealthProbeConfiguration.java
+++ b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/HealthProbeConfiguration.java
@@ -22,7 +22,7 @@ import org.apache.juneau.rest.health.*;
import jakarta.servlet.*;
/**
- * Opt-in probe configuration that auto-mounts {@link BasicHealthResource}.
+ * Opt-in probe configuration that auto-mounts {@link HealthServlet}.
*
* @since 9.5.0
*/
@@ -48,6 +48,6 @@ public class HealthProbeConfiguration {
@Bean(name="healthProbeServlet")
@ConditionalOnMissingBean(name="healthProbeServlet")
public Servlet healthProbeServlet() {
- return new BasicHealthResource();
+ return new HealthServlet();
}
}
diff --git a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/HelloWorldResource.java b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/HelloWorldResource.java
index 72ffd14264..f0c7c358dc 100644
--- a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/HelloWorldResource.java
+++ b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/HelloWorldResource.java
@@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.*;
@Rest(title = "Hello World", description = "An example of the simplest-possible resource", path = "/helloWorld")
@HtmlDocConfig(aside = { "<div style='max-width:400px' class='text'>", "\t<p>This page shows a resource that simply response with a 'Hello world!' message</p>",
"\t<p>The POJO serialized is a simple String.</p>", "</div>" })
-public class HelloWorldResource extends BasicRestObject {
+public class HelloWorldResource extends BasicRestResource {
private final String message;
diff --git a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/classic/MockConsole.java b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/classic/MockConsole.java
index ce2a283c14..a3e9e073f1 100644
--- a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/classic/MockConsole.java
+++ b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/classic/MockConsole.java
@@ -35,7 +35,7 @@ import org.apache.juneau.assertions.*;
* <p class='bjava'>
* <jc>// A simple REST API that echos a posted bean.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyRest <jk>extends</jk> BasicRestObject {
+ * <jk>public class</jk> MyRest <jk>extends</jk> BasicRestResource {
* <ja>@RestPost</ja>(<js>"/bean"</js>)
* <jk>public</jk> Bean postBean(<ja>@Content</ja> Bean <jv>bean</jv>) {
* <jk>return</jk> <jv>bean</jv>;
diff --git a/juneau-rest/juneau-rest-server-rdf/src/main/java/org/apache/juneau/rest/config/BasicUniversalJenaConfig.java b/juneau-rest/juneau-rest-server-rdf/src/main/java/org/apache/juneau/rest/config/BasicUniversalJenaConfig.java
index 2259e4638e..ad9bf1c86d 100644
--- a/juneau-rest/juneau-rest-server-rdf/src/main/java/org/apache/juneau/rest/config/BasicUniversalJenaConfig.java
+++ b/juneau-rest/juneau-rest-server-rdf/src/main/java/org/apache/juneau/rest/config/BasicUniversalJenaConfig.java
@@ -129,7 +129,7 @@ import org.apache.juneau.xml.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicUniversalJenaConfig { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicUniversalJenaConfig { ... }
* </p>
*
* <p>
@@ -142,8 +142,8 @@ import org.apache.juneau.xml.*;
* <ul class='javatreec'>
* <li class='jc'>{@link BasicRestServlet}
* <li class='jc'>{@link BasicRestServletGroup}
- * <li class='jc'>{@link BasicRestObject}
- * <li class='jc'>{@link BasicRestObjectGroup}
+ * <li class='jc'>{@link BasicRestResource}
+ * <li class='jc'>{@link BasicRestResourceGroup}
* </ul>
* <li class='link'>{doc jrs.AnnotatedClasses}
* </ul>
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
index cffb7cd4f8..de48cb3c36 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServlet.java
@@ -16,19 +16,15 @@
*/
package org.apache.juneau.rest.springboot;
-import java.util.*;
-
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.servlet.*;
-import org.apache.juneau.rest.stats.*;
+import org.apache.juneau.rest.convention.*;
+import org.apache.juneau.rest.ops.*;
/**
- * Subclass of {@link SpringRestServlet} with default settings and standard methods defined.
+ * Subclass of {@link SpringRestServlet} with default settings and standard endpoints defined.
*
* <p>
* Meant as base class for top-level REST resources in Spring Boot environments.
@@ -38,7 +34,8 @@ import org.apache.juneau.rest.stats.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations}.
+ * The residual cross-cutting endpoints are supplied by single-responsibility op-mixins ({@link ErrorMixin},
+ * {@link HtdocMixin}, {@link StatsMixin}, and {@link FaviconMixin}).
*
* <h5 class='section'>See Also:</h5><ul>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestServerSpringbootBasics">juneau-rest-server-springboot Basics</a>
@@ -47,26 +44,27 @@ import org.apache.juneau.rest.stats.*;
*
* @serial exclude
*/
-@Rest
-public abstract class BasicSpringRestServlet extends SpringRestServlet implements BasicRestOperations, BasicUniversalConfig {
- private static final long serialVersionUID = 1L;
-
- @Override /* Overridden from BasicRestConfig */
- public void error() {}
-
- @Override /* Overridden from BasicRestConfig */
- public HttpResource getFavIcon() {
- var favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
- return getHtdoc(favIcon, null);
+// @formatter:off
+@Rest(mixins={ErrorMixin.class, HtdocMixin.class, StatsMixin.class, FaviconMixin.class})
+@HtmlDocConfig(
+ // Basic page navigation links.
+ navlinks={
+ "up: request:/..",
+ "api: servlet:/api",
+ "stats: servlet:/stats"
}
-
- @Override /* Overridden from BasicRestConfig */
- public HttpResource getHtdoc(@Path("/*") String path, Locale locale) throws NotFound {
- return getContext().getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
- }
-
- @Override /* Overridden from BasicRestConfig */
- public RestContextStats getStats(RestRequest req) {
- return req.getContext().getStats();
- }
-}
\ No newline at end of file
+)
+@JsonSchemaConfig(
+ // Add descriptions to the following types when not specified:
+ addDescriptionsTo="bean,collection,array,map,enum",
+ // Add example to the following types:
+ addExamplesTo="bean,collection,array,map",
+ // Don't generate schema information on the Swagger / OpenApi beans themselves or HTML beans.
+ ignoreTypes="Swagger,OpenApi,org.apache.juneau.bean.html5.*",
+ // Use $ref references for bean definitions to reduce duplication in generated specs.
+ useBeanDefs="true"
+)
+// @formatter:on
+public abstract class BasicSpringRestServlet extends SpringRestServlet implements BasicUniversalConfig {
+ private static final long serialVersionUID = 1L;
+}
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
index 50aa13814f..0f05aa98b9 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/BasicSpringRestServletGroup.java
@@ -16,9 +16,10 @@
*/
package org.apache.juneau.rest.springboot;
+import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.beans.*;
import org.apache.juneau.rest.config.*;
-import org.apache.juneau.rest.servlet.*;
/**
* Specialized subclass of {@link BasicSpringRestServlet} for showing "group" pages.
@@ -31,7 +32,10 @@ import org.apache.juneau.rest.servlet.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations}.
+ * Adds the group-navigation endpoint ({@code GET /}) as a concrete method on top of the residual op-mixins
+ * inherited from {@link BasicSpringRestServlet}. The navigation page is rendered as a method of the host
+ * resource (rather than a sub-context mixin) so it inherits the host's
+ * {@link org.apache.juneau.html.annotation.HtmlDocConfig @HtmlDocConfig} page decoration.
*
* <p>
* Children are attached to this resource using the {@link Rest#children() @Rest(children)} annotation.
@@ -47,6 +51,21 @@ import org.apache.juneau.rest.servlet.*;
@SuppressWarnings({
"java:S110" // Inheritance depth acceptable for BasicSpringRestServletGroup hierarchy
})
-public abstract class BasicSpringRestServletGroup extends BasicSpringRestServlet implements BasicGroupOperations {
+public abstract class BasicSpringRestServletGroup extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
+
+ /**
+ * [GET /] - Get child resources.
+ *
+ * <p>
+ * Returns a bean that lists and allows navigation to child resources. Default implementation
+ * delegates to {@link ChildResourceDescriptions#of(RestRequest)}; subclasses may override.
+ *
+ * @param req The HTTP request.
+ * @return The bean containing links to the child resources.
+ */
+ @RestGet(path="/", summary="Navigation page")
+ public ChildResourceDescriptions getChildren(RestRequest req) {
+ return ChildResourceDescriptions.of(req);
+ }
}
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations.java b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations.java
index 3bbb5d9395..5b4bb37cce 100644
--- a/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations.java
+++ b/juneau-rest/juneau-rest-server-springboot/src/main/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations.java
@@ -34,7 +34,7 @@ import org.springframework.boot.web.servlet.*;
* <p class='bjava'>
* <ja>@Bean</ja>
* <jk>public</jk> ServletRegistrationBean<?> jspServlet(BeanStore <jv>beanStore</jv>) {
- * <jk>return</jk> JuneauServletRegistrations.<jsm>forServlet</jsm>(<jk>new</jk> BasicJspServlet(), <jv>beanStore</jv>);
+ * <jk>return</jk> JuneauServletRegistrations.<jsm>forServlet</jsm>(<jk>new</jk> JspServlet(), <jv>beanStore</jv>);
* }
* </p>
*
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerResource.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerMixin.java
similarity index 93%
rename from juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerResource.java
rename to juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerMixin.java
index 021ef69916..b458d20c58 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerResource.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerMixin.java
@@ -36,7 +36,7 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicFreemarkerResource.class)}; the host then:
+ * {@link Rest#mixins() @Rest(mixins=FreemarkerMixin.class)}; the host then:
*
* <ol class='spaced-list'>
* <li>Gains a default mount at {@code /freemarker/*} that serves raw FreeMarker templates from
@@ -52,11 +52,11 @@ import org.apache.juneau.rest.view.*;
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicFreemarkerResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=FreemarkerMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicFreemarkerResource freemarker() {
- * <jk>return</jk> BasicFreemarkerResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> FreemarkerMixin freemarker() {
+ * <jk>return</jk> FreemarkerMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .templateSuffix(<js>".ftlh"</js>)
* .build();
@@ -140,9 +140,9 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* A host with {@code /templates/} and {@code /admin/templates/} template trees registers two
- * {@code BasicFreemarkerResource} beans, each mounted via a subclass declaring its own op-level
+ * {@code FreemarkerMixin} beans, each mounted via a subclass declaring its own op-level
* {@code @RestGet(path=...)} override and its own {@code basePath}. See the
- * {@code BasicFreemarkerResource_MockRest_Test} test in {@code juneau-utest} for the canonical
+ * {@code FreemarkerMixin_MockRest_Test} test in {@code juneau-utest} for the canonical
* pattern.
*
* <h5 class='section'>OpenAPI surface:</h5>
@@ -164,7 +164,7 @@ import org.apache.juneau.rest.view.*;
@Rest(
responseProcessors={FreemarkerViewRenderer.class}
)
-public class BasicFreemarkerResource implements RawTemplateDispatcher {
+public class FreemarkerMixin implements RawTemplateDispatcher {
/** Default base path applied when no {@link Builder#basePath(String)} call has been made. */
public static final String DEFAULT_BASE_PATH = "/";
@@ -201,9 +201,9 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
* <p>
* The mixin walk falls back to this constructor when the
* {@link org.apache.juneau.commons.inject.BeanStore BeanStore} does not have a registered
- * {@code BasicFreemarkerResource} bean.
+ * {@code FreemarkerMixin} bean.
*/
- public BasicFreemarkerResource() {
+ public FreemarkerMixin() {
this(create());
}
@@ -212,7 +212,7 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
*
* @param builder The builder. Must not be {@code null}.
*/
- protected BasicFreemarkerResource(Builder builder) {
+ protected FreemarkerMixin(Builder builder) {
basePath = builder.basePath;
templateSuffix = builder.templateSuffix;
cacheTemplates = builder.cacheTemplates;
@@ -329,7 +329,7 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
*/
protected Configuration buildDefaultConfiguration() {
var cfg = new Configuration(Configuration.VERSION_2_3_34);
- cfg.setClassLoaderForTemplateLoading(BasicFreemarkerResource.class.getClassLoader(), toResourceRoot(basePath));
+ cfg.setClassLoaderForTemplateLoading(FreemarkerMixin.class.getClassLoader(), toResourceRoot(basePath));
cfg.setDefaultEncoding("UTF-8");
cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);
cfg.setTemplateUpdateDelayMilliseconds(cacheTemplates ? Long.MAX_VALUE : 0L);
@@ -476,7 +476,7 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
}
/**
- * Builder for {@link BasicFreemarkerResource}.
+ * Builder for {@link FreemarkerMixin}.
*/
public static class Builder {
@@ -484,19 +484,19 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
private String templateSuffix = DEFAULT_TEMPLATE_SUFFIX;
private boolean cacheTemplates = DEFAULT_CACHE_TEMPLATES;
- /** Constructor — package access for {@link BasicFreemarkerResource#create()}. */
+ /** Constructor — package access for {@link FreemarkerMixin#create()}. */
protected Builder() {}
/**
* Sets the classpath base path under which template resources are resolved.
*
* <p>
- * Defaults to {@link BasicFreemarkerResource#DEFAULT_BASE_PATH "/"}. A typical configured
+ * Defaults to {@link FreemarkerMixin#DEFAULT_BASE_PATH "/"}. A typical configured
* value is {@code "/templates/"} — the same Spring-Boot-compatible layout
* convention the sibling JSP / Thymeleaf / Mustache bridges use.
*
* @param value The base path. {@code null} or blank values reset to the default
- * {@link BasicFreemarkerResource#DEFAULT_BASE_PATH}.
+ * {@link FreemarkerMixin#DEFAULT_BASE_PATH}.
* @return This object.
*/
public Builder basePath(String value) {
@@ -509,12 +509,12 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
* (idempotent).
*
* <p>
- * Defaults to {@link BasicFreemarkerResource#DEFAULT_TEMPLATE_SUFFIX ""} (no implicit
+ * Defaults to {@link FreemarkerMixin#DEFAULT_TEMPLATE_SUFFIX ""} (no implicit
* suffix — literal template names). Typical configured values are {@code ".ftlh"}
* (HTML auto-escape) or {@code ".ftl"} (no auto-escape).
*
* @param value The new suffix. {@code null} resets to
- * {@link BasicFreemarkerResource#DEFAULT_TEMPLATE_SUFFIX}.
+ * {@link FreemarkerMixin#DEFAULT_TEMPLATE_SUFFIX}.
* @return This object.
*/
public Builder templateSuffix(String value) {
@@ -526,7 +526,7 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
* Sets the template-cache flag for the bridge-default configuration.
*
* <p>
- * Defaults to {@link BasicFreemarkerResource#DEFAULT_CACHE_TEMPLATES true} (cache
+ * Defaults to {@link FreemarkerMixin#DEFAULT_CACHE_TEMPLATES true} (cache
* forever — production-safe). Set {@code false} to enable dev hot-reload (FreeMarker
* re-checks the underlying resource on every render).
*
@@ -570,14 +570,14 @@ public class BasicFreemarkerResource implements RawTemplateDispatcher {
}
/**
- * Builds the {@link BasicFreemarkerResource}.
+ * Builds the {@link FreemarkerMixin}.
*
- * @return A new {@link BasicFreemarkerResource} instance.
+ * @return A new {@link FreemarkerMixin} instance.
*/
- public BasicFreemarkerResource build() {
+ public FreemarkerMixin build() {
if (basePath == null)
throw illegalArg("basePath must not be null");
- return new BasicFreemarkerResource(this);
+ return new FreemarkerMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerResource.java
similarity index 52%
copy from juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java
copy to juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerResource.java
index edab5c2ad3..d8a04858ee 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerResource.java
@@ -20,55 +20,48 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicFreemarkerResource} mixin.
+ * Child-resource flavor of the {@link FreemarkerMixin} mixin.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /freemarker/*} and renders raw FreeMarker
- * templates by delegating to a shared {@link BasicFreemarkerResource} instance — the same
- * {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
- *
- * <p>
- * Whereas the {@link BasicFreemarkerResource} mixin pins its op at {@code /freemarker/*} for
- * composition into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/freemarker/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=FreemarkerResource.class)}
+ * under a parent at the subtree {@code /freemarker} and renders raw FreeMarker templates by delegating to
+ * a shared {@link FreemarkerMixin} instance — the same {@link RawTemplateDispatcher} implementation
+ * the mixin and {@link FreemarkerServlet servlet} flavors use, so the three forms cannot drift.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFreemarkerResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link FreemarkerMixin}
+ * <li class='jc'>{@link FreemarkerServlet}
+ * <li class='jc'>{@link ViewResource}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/FreemarkerViewSupport">FreeMarker View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
@Rest(
- paths="/freemarker/*",
+ path="/freemarker",
responseProcessors={FreemarkerViewRenderer.class}
)
-public class BasicFreemarkerServlet extends BasicViewServlet {
-
- private static final long serialVersionUID = 1L;
+public class FreemarkerResource extends ViewResource {
- private final transient BasicFreemarkerResource delegate;
+ private final transient FreemarkerMixin delegate;
- /** No-arg constructor — uses a default {@link BasicFreemarkerResource} delegate. */
- public BasicFreemarkerServlet() {
- this(BasicFreemarkerResource.create().build());
+ /** No-arg constructor — uses a default {@link FreemarkerMixin} delegate. */
+ public FreemarkerResource() {
+ this(FreemarkerMixin.create().build());
}
/**
* Delegate constructor.
*
- * @param delegate The shared FreeMarker renderer/mixin this servlet delegates raw dispatch to.
- * Must not be {@code null}.
+ * @param delegate The shared FreeMarker renderer/mixin this child delegates raw dispatch to. Must
+ * not be {@code null}.
*/
- protected BasicFreemarkerServlet(BasicFreemarkerResource delegate) {
+ protected FreemarkerResource(FreemarkerMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewResource */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerServlet.java
similarity index 72%
rename from juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java
rename to juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerServlet.java
index edab5c2ad3..3b5ebcdafe 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/BasicFreemarkerServlet.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerServlet.java
@@ -20,22 +20,22 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicFreemarkerResource} mixin.
+ * Standalone servlet companion of the {@link FreemarkerMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /freemarker/*} and renders raw FreeMarker
- * templates by delegating to a shared {@link BasicFreemarkerResource} instance — the same
+ * templates by delegating to a shared {@link FreemarkerMixin} instance — the same
* {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicFreemarkerResource} mixin pins its op at {@code /freemarker/*} for
+ * Whereas the {@link FreemarkerMixin} mixin pins its op at {@code /freemarker/*} for
* composition into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/freemarker/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * {@link ViewServlet}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFreemarkerResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link FreemarkerMixin}
+ * <li class='jc'>{@link ViewServlet}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/FreemarkerViewSupport">FreeMarker View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
@@ -47,15 +47,15 @@ import org.apache.juneau.rest.view.*;
paths="/freemarker/*",
responseProcessors={FreemarkerViewRenderer.class}
)
-public class BasicFreemarkerServlet extends BasicViewServlet {
+public class FreemarkerServlet extends ViewServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicFreemarkerResource delegate;
+ private final transient FreemarkerMixin delegate;
- /** No-arg constructor — uses a default {@link BasicFreemarkerResource} delegate. */
- public BasicFreemarkerServlet() {
- this(BasicFreemarkerResource.create().build());
+ /** No-arg constructor — uses a default {@link FreemarkerMixin} delegate. */
+ public FreemarkerServlet() {
+ this(FreemarkerMixin.create().build());
}
/**
@@ -64,11 +64,11 @@ public class BasicFreemarkerServlet extends BasicViewServlet {
* @param delegate The shared FreeMarker renderer/mixin this servlet delegates raw dispatch to.
* Must not be {@code null}.
*/
- protected BasicFreemarkerServlet(BasicFreemarkerResource delegate) {
+ protected FreemarkerServlet(FreemarkerMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewServlet */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerView.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerView.java
index 588edefa58..5b5dae0961 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerView.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerView.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.view.*;
* render an Apache FreeMarker template.
*
* <p>
- * Companion to {@link BasicFreemarkerResource} and {@link FreemarkerViewRenderer}: the mixin sets
+ * Companion to {@link FreemarkerMixin} and {@link FreemarkerViewRenderer}: the mixin sets
* up the {@code /freemarker/*} mount and registers the renderer; the renderer detects
* {@code FreemarkerView} returns in the response-processor chain and asks the configured
* {@code freemarker.template.Configuration} to {@code getTemplate(templateName)} and then
@@ -62,7 +62,7 @@ import org.apache.juneau.rest.view.*;
* <h5 class='section'>Template suffix:</h5>
*
* <p>
- * The {@link BasicFreemarkerResource.Builder#templateSuffix(String) templateSuffix(...)} builder
+ * The {@link FreemarkerMixin.Builder#templateSuffix(String) templateSuffix(...)} builder
* knob lets the bridge append a suffix (e.g. {@code ".ftlh"}) to template names that don't
* already end with it, so callers can write {@code FreemarkerView.of("hello")} and have the
* bridge resolve it as {@code "hello.ftlh"} on the classpath (idempotent — explicit suffix
@@ -77,7 +77,7 @@ import org.apache.juneau.rest.view.*;
* singleton built once and returned from many handlers).
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFreemarkerResource}
+ * <li class='jc'>{@link FreemarkerMixin}
* <li class='jc'>{@link FreemarkerViewRenderer}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/FreemarkerViewSupport">FreeMarker View Support</a>
* </ul>
@@ -100,7 +100,7 @@ public final class FreemarkerView implements View {
* {@code "hello.ftlh"} resolves to {@code /templates/hello.ftlh} on the classpath.
*
* @param templateName The template name (configuration-relative, suffix optional when the
- * mixin's {@link BasicFreemarkerResource.Builder#templateSuffix(String) templateSuffix} is
+ * mixin's {@link FreemarkerMixin.Builder#templateSuffix(String) templateSuffix} is
* configured). Must not be {@code null} or blank.
* @return A new {@code FreemarkerView} instance.
* @throws IllegalArgumentException If {@code templateName} is {@code null} or blank.
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerViewRenderer.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerViewRenderer.java
index af2f21f02a..6bfd52b5c1 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerViewRenderer.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/FreemarkerViewRenderer.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.view.*;
* configured {@link Configuration} to render them directly onto the response writer.
*
* <p>
- * Auto-registered by {@link BasicFreemarkerResource} via
+ * Auto-registered by {@link FreemarkerMixin} via
* {@link org.apache.juneau.rest.annotation.Rest#responseProcessors() @Rest(responseProcessors=...)}
* — callers who add the mixin don't need to wire up this class explicitly. Callers who want
* to handle {@code FreemarkerView} returns <i>without</i> adopting the mixin can add this class
@@ -42,7 +42,7 @@ import org.apache.juneau.rest.view.*;
* <ol class='spaced-list'>
* <li>Inspect the response content. If the value is not a {@link FreemarkerView}, return
* {@link ResponseProcessor#NEXT NEXT} so the rest of the chain runs.
- * <li>Read the active {@link BasicFreemarkerResource} from the {@code RestContext} bean store
+ * <li>Read the active {@link FreemarkerMixin} from the {@code RestContext} bean store
* to discover the {@link Configuration} (lazy default if no configuration bean is
* registered) and the optional template-suffix knob.
* <li>Apply every entry from {@link FreemarkerView#getResponseHeaders()} via
@@ -59,7 +59,7 @@ import org.apache.juneau.rest.view.*;
* </ol>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFreemarkerResource}
+ * <li class='jc'>{@link FreemarkerMixin}
* <li class='jc'>{@link FreemarkerView}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/FreemarkerViewSupport">FreeMarker View Support</a>
@@ -100,11 +100,11 @@ public class FreemarkerViewRenderer implements ViewRenderer {
return NEXT;
// Resolve the bridge resource (carries Configuration + cached default + templateSuffix).
- // Fall back to a fresh BasicFreemarkerResource when the renderer is used standalone
+ // Fall back to a fresh FreemarkerMixin when the renderer is used standalone
// without the mixin.
var bridge = req.getContext().getBeanStore()
- .getBean(BasicFreemarkerResource.class)
- .orElseGet(BasicFreemarkerResource::new);
+ .getBean(FreemarkerMixin.class)
+ .orElseGet(FreemarkerMixin::new);
// Apply caller-supplied response headers first so a caller-provided Content-Type wins
// over the bridge's default below.
diff --git a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/package-info.java b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/package-info.java
index 3389612aff..b8bc74d27f 100644
--- a/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/package-info.java
+++ b/juneau-rest/juneau-rest-server-view-freemarker/src/main/java/org/apache/juneau/rest/view/freemarker/package-info.java
@@ -23,7 +23,7 @@
* <a href="https://freemarker.apache.org/">Apache FreeMarker</a> templates:
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.view.freemarker.BasicFreemarkerResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.view.freemarker.FreemarkerMixin} —
* mixin that renders raw FreeMarker templates from the importer's classpath under
* {@code /freemarker/*} and auto-registers
* {@link org.apache.juneau.rest.view.freemarker.FreemarkerViewRenderer}.
@@ -42,11 +42,11 @@
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicFreemarkerResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=FreemarkerMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicFreemarkerResource freemarker() {
- * <jk>return</jk> BasicFreemarkerResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> FreemarkerMixin freemarker() {
+ * <jk>return</jk> FreemarkerMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .templateSuffix(<js>".ftlh"</js>)
* .build();
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspResource.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspMixin.java
similarity index 90%
rename from juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspResource.java
rename to juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspMixin.java
index 6bf88ba0ec..39b5620a4d 100644
--- a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspResource.java
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspMixin.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicJspResource.class)}; the host then:
+ * {@link Rest#mixins() @Rest(mixins=JspMixin.class)}; the host then:
*
* <ol class='spaced-list'>
* <li>Gains a default mount at {@code /jsp/*} that serves raw {@code .jsp} resources from the
@@ -46,11 +46,11 @@ import org.apache.juneau.rest.view.*;
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicJspResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=JspMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicJspResource jsp() {
- * <jk>return</jk> BasicJspResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> JspMixin jsp() {
+ * <jk>return</jk> JspMixin.<jsm>create</jsm>()
* .basePath(<js>"/WEB-INF/views/"</js>)
* .build();
* }
@@ -117,9 +117,9 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* A host with {@code /views/} JSPs and {@code /admin/views/} JSPs registers two
- * {@code BasicJspResource} beans, each mounted via a subclass declaring its own op-level
+ * {@code JspMixin} beans, each mounted via a subclass declaring its own op-level
* {@code @RestGet(path=...)} override and its own {@code basePath}. See the
- * {@code BasicJspResource_MultiBasePath_Test} test in {@code juneau-utest} for the canonical
+ * {@code JspMixin_MultiBasePath_Test} test in {@code juneau-utest} for the canonical
* pattern.
*
* <h5 class='section'>OpenAPI surface:</h5>
@@ -141,7 +141,7 @@ import org.apache.juneau.rest.view.*;
@Rest(
responseProcessors={JspViewRenderer.class}
)
-public class BasicJspResource implements RawTemplateDispatcher {
+public class JspMixin implements RawTemplateDispatcher {
/** Default base path applied when no {@link Builder#basePath(String)} call has been made. */
public static final String DEFAULT_BASE_PATH = "/";
@@ -162,9 +162,9 @@ public class BasicJspResource implements RawTemplateDispatcher {
*
* <p>
* The mixin walk falls back to this constructor when the {@link org.apache.juneau.commons.inject.BeanStore
- * BeanStore} does not have a registered {@code BasicJspResource} bean.
+ * BeanStore} does not have a registered {@code JspMixin} bean.
*/
- public BasicJspResource() {
+ public JspMixin() {
this(create());
}
@@ -173,7 +173,7 @@ public class BasicJspResource implements RawTemplateDispatcher {
*
* @param builder The builder. Must not be {@code null}.
*/
- protected BasicJspResource(Builder builder) {
+ protected JspMixin(Builder builder) {
basePath = builder.basePath;
}
@@ -247,25 +247,25 @@ public class BasicJspResource implements RawTemplateDispatcher {
}
/**
- * Builder for {@link BasicJspResource}.
+ * Builder for {@link JspMixin}.
*/
public static class Builder {
private String basePath = DEFAULT_BASE_PATH;
- /** Constructor — package access for {@link BasicJspResource#create()}. */
+ /** Constructor — package access for {@link JspMixin#create()}. */
protected Builder() {}
/**
* Sets the classpath / webapp base path under which {@code .jsp} resources are resolved.
*
* <p>
- * Defaults to {@link BasicJspResource#DEFAULT_BASE_PATH "/"}. A typical configured value
+ * Defaults to {@link JspMixin#DEFAULT_BASE_PATH "/"}. A typical configured value
* is {@code "/WEB-INF/views/"} — the Servlet-spec convention for hiding template
* files from direct HTTP access.
*
* @param value The base path. {@code null} or blank values reset to the default
- * {@link BasicJspResource#DEFAULT_BASE_PATH}.
+ * {@link JspMixin#DEFAULT_BASE_PATH}.
* @return This object.
*/
public Builder basePath(String value) {
@@ -283,14 +283,14 @@ public class BasicJspResource implements RawTemplateDispatcher {
}
/**
- * Builds the {@link BasicJspResource}.
+ * Builds the {@link JspMixin}.
*
- * @return A new {@link BasicJspResource} instance.
+ * @return A new {@link JspMixin} instance.
*/
- public BasicJspResource build() {
+ public JspMixin build() {
if (basePath == null)
throw illegalArg("basePath must not be null");
- return new BasicJspResource(this);
+ return new JspMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspResource.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspResource.java
new file mode 100644
index 0000000000..8e5b08fed2
--- /dev/null
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspResource.java
@@ -0,0 +1,68 @@
+/*
+ * 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.rest.view.jsp;
+
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.view.*;
+
+/**
+ * Child-resource flavor of the {@link JspMixin} mixin.
+ *
+ * <p>
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=JspResource.class)} under a
+ * parent at the subtree {@code /jsp} and serves raw {@code .jsp} resources by delegating to a shared
+ * {@link JspMixin} instance — the same {@link RawTemplateDispatcher} implementation the mixin and
+ * {@link JspServlet servlet} flavors use, so the three forms cannot drift.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link JspMixin}
+ * <li class='jc'>{@link JspServlet}
+ * <li class='jc'>{@link ViewResource}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JspViewSupport">JSP View Support</a>
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+@Rest(
+ path="/jsp",
+ responseProcessors={JspViewRenderer.class}
+)
+public class JspResource extends ViewResource {
+
+ private final transient JspMixin delegate;
+
+ /** No-arg constructor — uses a default {@link JspMixin} delegate. */
+ public JspResource() {
+ this(JspMixin.create().build());
+ }
+
+ /**
+ * Delegate constructor.
+ *
+ * @param delegate The shared JSP renderer/mixin this child delegates raw dispatch to. Must not be
+ * {@code null}.
+ */
+ protected JspResource(JspMixin delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override /* ViewResource */
+ protected RawTemplateDispatcher dispatcher() {
+ return delegate;
+ }
+}
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspServlet.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspServlet.java
similarity index 72%
rename from juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspServlet.java
rename to juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspServlet.java
index c0b0997d77..d4974e23bb 100644
--- a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/BasicJspServlet.java
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspServlet.java
@@ -20,37 +20,37 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicJspResource} mixin.
+ * Standalone servlet companion of the {@link JspMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /jsp/*} (a sibling of the host
* application's other servlets, e.g. {@code /rest/*}) and serves raw {@code .jsp} resources by
- * delegating to a shared {@link BasicJspResource} instance — the same
+ * delegating to a shared {@link JspMixin} instance — the same
* {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicJspResource} mixin pins its op at {@code /jsp/*} for composition into a
+ * Whereas the {@link JspMixin} mixin pins its op at {@code /jsp/*} for composition into a
* host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/jsp/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet} — eliminating the path-doubling that a mixin-shaped op would
+ * {@link ViewServlet} — eliminating the path-doubling that a mixin-shaped op would
* produce when the servlet itself is mounted at {@code /jsp/*}.
*
* <h5 class='figure'>Microservice registration:</h5>
*
* <p class='bjava'>
* <ja>@Bean</ja> Servlet jsp() {
- * <jk>return new</jk> BasicJspServlet(); <jc>// auto-mounted at /jsp/* by JettyServerComponent</jc>
+ * <jk>return new</jk> JspServlet(); <jc>// auto-mounted at /jsp/* by JettyServerComponent</jc>
* }
* </p>
*
* <p>
* The default mount {@code /jsp/*} can be relocated by overriding {@link #getPaths()} or via the
* programmatic {@code RestContext.Builder.paths(...)} rung; the underlying base path for resolving
- * {@code .jsp} files is configured on the {@link BasicJspResource} delegate.
+ * {@code .jsp} files is configured on the {@link JspMixin} delegate.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicJspResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link JspMixin}
+ * <li class='jc'>{@link ViewServlet}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JspViewSupport">JSP View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
@@ -62,15 +62,15 @@ import org.apache.juneau.rest.view.*;
paths="/jsp/*",
responseProcessors={JspViewRenderer.class}
)
-public class BasicJspServlet extends BasicViewServlet {
+public class JspServlet extends ViewServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicJspResource delegate;
+ private final transient JspMixin delegate;
- /** No-arg constructor — uses a default {@link BasicJspResource} delegate. */
- public BasicJspServlet() {
- this(BasicJspResource.create().build());
+ /** No-arg constructor — uses a default {@link JspMixin} delegate. */
+ public JspServlet() {
+ this(JspMixin.create().build());
}
/**
@@ -79,11 +79,11 @@ public class BasicJspServlet extends BasicViewServlet {
* @param delegate The shared JSP renderer/mixin this servlet delegates raw dispatch to. Must
* not be {@code null}.
*/
- protected BasicJspServlet(BasicJspResource delegate) {
+ protected JspServlet(JspMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewServlet */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspView.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspView.java
index 0e0d4811ff..a5118a77a7 100644
--- a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspView.java
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspView.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.view.*;
* render a JSP template.
*
* <p>
- * Companion to {@link BasicJspResource} and {@link JspViewRenderer}: the mixin sets up the
+ * Companion to {@link JspMixin} and {@link JspViewRenderer}: the mixin sets up the
* {@code /jsp/*} mount and registers the renderer; the renderer detects {@code JspView} returns
* in the response-processor chain and dispatches via
* {@link jakarta.servlet.RequestDispatcher#forward(jakarta.servlet.ServletRequest,
@@ -53,7 +53,7 @@ import org.apache.juneau.rest.view.*;
* once and returned from many handlers).
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicJspResource}
+ * <li class='jc'>{@link JspMixin}
* <li class='jc'>{@link JspViewRenderer}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JspViewSupport">JSP View Support</a>
* </ul>
@@ -70,7 +70,7 @@ public final class JspView implements View {
* Creates a new {@code JspView} carrying the given template name and no attributes.
*
* @param templateName The template name (relative to the
- * {@link BasicJspResource.Builder#basePath base path}). Must not be {@code null} or blank.
+ * {@link JspMixin.Builder#basePath base path}). Must not be {@code null} or blank.
* @return A new {@code JspView} instance.
* @throws IllegalArgumentException If {@code templateName} is {@code null} or blank.
*/
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspViewRenderer.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspViewRenderer.java
index e03090d13d..ef0104f76c 100644
--- a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspViewRenderer.java
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/JspViewRenderer.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.view.*;
* jakarta.servlet.ServletResponse) ServletContext.getRequestDispatcher(...).forward(...)}.
*
* <p>
- * Auto-registered by {@link BasicJspResource} via
+ * Auto-registered by {@link JspMixin} via
* {@link org.apache.juneau.rest.annotation.Rest#responseProcessors() @Rest(responseProcessors=...)}
* — callers who add the mixin don't need to wire up this class explicitly. Callers who want
* to handle {@code JspView} returns <i>without</i> adopting the mixin (e.g. mounting their own
@@ -44,7 +44,7 @@ import org.apache.juneau.rest.view.*;
* <li>Inspect the response content. If the value is not a {@link JspView}, return
* {@link ResponseProcessor#NEXT NEXT} so the rest of the chain runs (the standard POJO
* serializer / plain-text fallback handle non-{@code JspView} returns).
- * <li>Read the active {@link BasicJspResource} from the {@code RestContext} bean store to
+ * <li>Read the active {@link JspMixin} from the {@code RestContext} bean store to
* discover the configured base path; fall back to {@code "/"} when none is registered (a
* caller using the renderer standalone without the mixin).
* <li>Copy every entry from {@link JspView#getAttributes()} onto the request as a request
@@ -70,7 +70,7 @@ import org.apache.juneau.rest.view.*;
* accident; document the constraint for any user relying on {@code RestPreCall}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicJspResource}
+ * <li class='jc'>{@link JspMixin}
* <li class='jc'>{@link JspView}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JspViewSupport">JSP View Support</a>
@@ -103,11 +103,11 @@ public class JspViewRenderer implements ViewRenderer {
if (! (content instanceof JspView view))
return NEXT;
- // Resolve the base path. Prefer the registered BasicJspResource bean (which the mixin
+ // Resolve the base path. Prefer the registered JspMixin bean (which the mixin
// instantiates), fall back to "/" when the renderer is used standalone.
var basePath = req.getContext().getBeanStore()
- .getBean(BasicJspResource.class)
- .map(BasicJspResource::getBasePath)
+ .getBean(JspMixin.class)
+ .map(JspMixin::getBasePath)
.orElse("/");
// Copy attributes onto the request so the JSP / JSTL EL can resolve them.
@@ -120,7 +120,7 @@ public class JspViewRenderer implements ViewRenderer {
// A path that escapes basePath (e.g. template names assembled from user input that
// included ../ segments) is rejected with InternalServerError — template names are
// caller-controlled, so an escape attempt indicates a server-side bug, not a request-
- // side attack. (User-input flowing into JSP rendering is handled by BasicJspResource.render
+ // side attack. (User-input flowing into JSP rendering is handled by JspMixin.render
// which catches IAE and surfaces it as Forbidden.)
String target;
try {
@@ -156,7 +156,7 @@ public class JspViewRenderer implements ViewRenderer {
*
* <p>
* Delegates to {@link FileUtils#resolveVirtualPathSafely(String, String)} — the canonical
- * shared implementation reused by {@code BasicJspResource.render(...)} for the
+ * shared implementation reused by {@code JspMixin.render(...)} for the
* raw-{@code .jsp} dispatch path. Handles every {@code (basePath, template)} combination of
* trailing/leading slashes uniformly so callers can pass {@code basePath("/WEB-INF/views")} or
* {@code basePath("/WEB-INF/views/")} and {@code "hello.jsp"} or {@code "/hello.jsp"} without
@@ -164,7 +164,7 @@ public class JspViewRenderer implements ViewRenderer {
*
* <p>
* A {@code null} or empty {@code basePath} is normalized to {@code "/"} (the
- * {@link BasicJspResource#DEFAULT_BASE_PATH default}) before the boundary check runs.
+ * {@link JspMixin#DEFAULT_BASE_PATH default}) before the boundary check runs.
*
* @param basePath The base path (e.g. {@code "/WEB-INF/views/"}).
* @param template The template name (e.g. {@code "hello.jsp"}).
diff --git a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/package-info.java b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/package-info.java
index e3b9466209..ef14305a77 100644
--- a/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/package-info.java
+++ b/juneau-rest/juneau-rest-server-view-jsp/src/main/java/org/apache/juneau/rest/view/jsp/package-info.java
@@ -21,7 +21,7 @@
* Provides three sibling pieces that together let a Juneau REST resource render JSP templates:
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.view.jsp.BasicJspResource} — mixin that
+ * <li class='jc'>{@link org.apache.juneau.rest.view.jsp.JspMixin} — mixin that
* serves raw {@code .jsp} resources from the importer's classpath under
* {@code /jsp/*} and auto-registers {@link org.apache.juneau.rest.view.jsp.JspViewRenderer}.
* <li class='jc'>{@link org.apache.juneau.rest.view.jsp.JspView} — immutable value class
@@ -37,11 +37,11 @@
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicJspResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=JspMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicJspResource jsp() {
- * <jk>return</jk> BasicJspResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> JspMixin jsp() {
+ * <jk>return</jk> JspMixin.<jsm>create</jsm>()
* .basePath(<js>"/WEB-INF/views/"</js>)
* .build();
* }
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheResource.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheMixin.java
similarity index 93%
rename from juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheResource.java
rename to juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheMixin.java
index 1751960503..39125a11d7 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheResource.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheMixin.java
@@ -35,7 +35,7 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicMustacheResource.class)}; the host then:
+ * {@link Rest#mixins() @Rest(mixins=MustacheMixin.class)}; the host then:
*
* <ol class='spaced-list'>
* <li>Gains a default mount at {@code /mustache/*} that serves raw Mustache templates from the
@@ -51,11 +51,11 @@ import org.apache.juneau.rest.view.*;
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicMustacheResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=MustacheMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicMustacheResource mustache() {
- * <jk>return</jk> BasicMustacheResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> MustacheMixin mustache() {
+ * <jk>return</jk> MustacheMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .templateSuffix(<js>".mustache"</js>)
* .build();
@@ -131,9 +131,9 @@ import org.apache.juneau.rest.view.*;
*
* <p>
* A host with {@code /templates/} and {@code /admin/templates/} template trees registers two
- * {@code BasicMustacheResource} beans, each mounted via a subclass declaring its own op-level
+ * {@code MustacheMixin} beans, each mounted via a subclass declaring its own op-level
* {@code @RestGet(path=...)} override and its own {@code basePath}. See the
- * {@code BasicMustacheResource_MockRest_Test} test in {@code juneau-utest} for the canonical
+ * {@code MustacheMixin_MockRest_Test} test in {@code juneau-utest} for the canonical
* pattern.
*
* <h5 class='section'>OpenAPI surface:</h5>
@@ -155,7 +155,7 @@ import org.apache.juneau.rest.view.*;
@Rest(
responseProcessors={MustacheViewRenderer.class}
)
-public class BasicMustacheResource implements RawTemplateDispatcher {
+public class MustacheMixin implements RawTemplateDispatcher {
/** Default base path applied when no {@link Builder#basePath(String)} call has been made. */
public static final String DEFAULT_BASE_PATH = "/";
@@ -187,9 +187,9 @@ public class BasicMustacheResource implements RawTemplateDispatcher {
* <p>
* The mixin walk falls back to this constructor when the
* {@link org.apache.juneau.commons.inject.BeanStore BeanStore} does not have a registered
- * {@code BasicMustacheResource} bean.
+ * {@code MustacheMixin} bean.
*/
- public BasicMustacheResource() {
+ public MustacheMixin() {
this(create());
}
@@ -198,7 +198,7 @@ public class BasicMustacheResource implements RawTemplateDispatcher {
*
* @param builder The builder. Must not be {@code null}.
*/
- protected BasicMustacheResource(Builder builder) {
+ protected MustacheMixin(Builder builder) {
basePath = builder.basePath;
templateSuffix = builder.templateSuffix;
}
@@ -428,26 +428,26 @@ public class BasicMustacheResource implements RawTemplateDispatcher {
}
/**
- * Builder for {@link BasicMustacheResource}.
+ * Builder for {@link MustacheMixin}.
*/
public static class Builder {
private String basePath = DEFAULT_BASE_PATH;
private String templateSuffix = DEFAULT_TEMPLATE_SUFFIX;
- /** Constructor — package access for {@link BasicMustacheResource#create()}. */
+ /** Constructor — package access for {@link MustacheMixin#create()}. */
protected Builder() {}
/**
* Sets the classpath base path under which template resources are resolved.
*
* <p>
- * Defaults to {@link BasicMustacheResource#DEFAULT_BASE_PATH "/"}. A typical configured
+ * Defaults to {@link MustacheMixin#DEFAULT_BASE_PATH "/"}. A typical configured
* value is {@code "/templates/"} — the same Spring-Boot-compatible layout
* convention the sibling JSP / Thymeleaf bridges use.
*
* @param value The base path. {@code null} or blank values reset to the default
- * {@link BasicMustacheResource#DEFAULT_BASE_PATH}.
+ * {@link MustacheMixin#DEFAULT_BASE_PATH}.
* @return This object.
*/
public Builder basePath(String value) {
@@ -459,12 +459,12 @@ public class BasicMustacheResource implements RawTemplateDispatcher {
* Sets the suffix to append to template names that don't already end with it (idempotent).
*
* <p>
- * Defaults to {@link BasicMustacheResource#DEFAULT_TEMPLATE_SUFFIX ""} (no implicit
+ * Defaults to {@link MustacheMixin#DEFAULT_TEMPLATE_SUFFIX ""} (no implicit
* suffix — literal template names). Typical configured value is
* {@code ".mustache"}, the mustache.java convention.
*
* @param value The new suffix. {@code null} resets to
- * {@link BasicMustacheResource#DEFAULT_TEMPLATE_SUFFIX}.
+ * {@link MustacheMixin#DEFAULT_TEMPLATE_SUFFIX}.
* @return This object.
*/
public Builder templateSuffix(String value) {
@@ -491,14 +491,14 @@ public class BasicMustacheResource implements RawTemplateDispatcher {
}
/**
- * Builds the {@link BasicMustacheResource}.
+ * Builds the {@link MustacheMixin}.
*
- * @return A new {@link BasicMustacheResource} instance.
+ * @return A new {@link MustacheMixin} instance.
*/
- public BasicMustacheResource build() {
+ public MustacheMixin build() {
if (basePath == null)
throw illegalArg("basePath must not be null");
- return new BasicMustacheResource(this);
+ return new MustacheMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheResource.java
similarity index 52%
copy from juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java
copy to juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheResource.java
index 30fb29ea55..9e79a47375 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheResource.java
@@ -20,55 +20,48 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicMustacheResource} mixin.
+ * Child-resource flavor of the {@link MustacheMixin} mixin.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /mustache/*} and renders raw Mustache
- * templates by delegating to a shared {@link BasicMustacheResource} instance — the same
- * {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
- *
- * <p>
- * Whereas the {@link BasicMustacheResource} mixin pins its op at {@code /mustache/*} for composition
- * into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/mustache/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=MustacheResource.class)}
+ * under a parent at the subtree {@code /mustache} and renders raw Mustache templates by delegating to a
+ * shared {@link MustacheMixin} instance — the same {@link RawTemplateDispatcher} implementation the
+ * mixin and {@link MustacheServlet servlet} flavors use, so the three forms cannot drift.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicMustacheResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link MustacheMixin}
+ * <li class='jc'>{@link MustacheServlet}
+ * <li class='jc'>{@link ViewResource}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MustacheViewSupport">Mustache View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
@Rest(
- paths="/mustache/*",
+ path="/mustache",
responseProcessors={MustacheViewRenderer.class}
)
-public class BasicMustacheServlet extends BasicViewServlet {
-
- private static final long serialVersionUID = 1L;
+public class MustacheResource extends ViewResource {
- private final transient BasicMustacheResource delegate;
+ private final transient MustacheMixin delegate;
- /** No-arg constructor — uses a default {@link BasicMustacheResource} delegate. */
- public BasicMustacheServlet() {
- this(BasicMustacheResource.create().build());
+ /** No-arg constructor — uses a default {@link MustacheMixin} delegate. */
+ public MustacheResource() {
+ this(MustacheMixin.create().build());
}
/**
* Delegate constructor.
*
- * @param delegate The shared Mustache renderer/mixin this servlet delegates raw dispatch to.
- * Must not be {@code null}.
+ * @param delegate The shared Mustache renderer/mixin this child delegates raw dispatch to. Must
+ * not be {@code null}.
*/
- protected BasicMustacheServlet(BasicMustacheResource delegate) {
+ protected MustacheResource(MustacheMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewResource */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheServlet.java
similarity index 72%
rename from juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java
rename to juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheServlet.java
index 30fb29ea55..858888c112 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/BasicMustacheServlet.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheServlet.java
@@ -20,22 +20,22 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicMustacheResource} mixin.
+ * Standalone servlet companion of the {@link MustacheMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /mustache/*} and renders raw Mustache
- * templates by delegating to a shared {@link BasicMustacheResource} instance — the same
+ * templates by delegating to a shared {@link MustacheMixin} instance — the same
* {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicMustacheResource} mixin pins its op at {@code /mustache/*} for composition
+ * Whereas the {@link MustacheMixin} mixin pins its op at {@code /mustache/*} for composition
* into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/mustache/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * {@link ViewServlet}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicMustacheResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link MustacheMixin}
+ * <li class='jc'>{@link ViewServlet}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MustacheViewSupport">Mustache View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
@@ -47,15 +47,15 @@ import org.apache.juneau.rest.view.*;
paths="/mustache/*",
responseProcessors={MustacheViewRenderer.class}
)
-public class BasicMustacheServlet extends BasicViewServlet {
+public class MustacheServlet extends ViewServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicMustacheResource delegate;
+ private final transient MustacheMixin delegate;
- /** No-arg constructor — uses a default {@link BasicMustacheResource} delegate. */
- public BasicMustacheServlet() {
- this(BasicMustacheResource.create().build());
+ /** No-arg constructor — uses a default {@link MustacheMixin} delegate. */
+ public MustacheServlet() {
+ this(MustacheMixin.create().build());
}
/**
@@ -64,11 +64,11 @@ public class BasicMustacheServlet extends BasicViewServlet {
* @param delegate The shared Mustache renderer/mixin this servlet delegates raw dispatch to.
* Must not be {@code null}.
*/
- protected BasicMustacheServlet(BasicMustacheResource delegate) {
+ protected MustacheServlet(MustacheMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewServlet */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheView.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheView.java
index 4a431d5e9f..350d007310 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheView.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheView.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.view.*;
* render a Mustache template.
*
* <p>
- * Companion to {@link BasicMustacheResource} and {@link MustacheViewRenderer}: the mixin sets up
+ * Companion to {@link MustacheMixin} and {@link MustacheViewRenderer}: the mixin sets up
* the {@code /mustache/*} mount and registers the renderer; the renderer detects
* {@code MustacheView} returns in the response-processor chain and asks the configured
* {@code com.github.mustachejava.MustacheFactory} to {@code compile(templateName)} and then
@@ -57,7 +57,7 @@ import org.apache.juneau.rest.view.*;
* Unlike the Thymeleaf bridge (which always appends {@code .html} via the engine resolver's
* suffix setting), mustache.java does not have a built-in resolver-suffix concept — the
* literal template name is what {@code factory.compile(...)} sees. The
- * {@link BasicMustacheResource.Builder#templateSuffix(String) templateSuffix(...)} builder knob
+ * {@link MustacheMixin.Builder#templateSuffix(String) templateSuffix(...)} builder knob
* fills the gap: when set, the bridge appends the suffix to template names that don't already
* end with it (idempotent), so the caller can write {@code MustacheView.of("hello")} and the
* bridge resolves it as {@code "hello.mustache"} on the classpath.
@@ -71,7 +71,7 @@ import org.apache.juneau.rest.view.*;
* singleton built once and returned from many handlers).
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicMustacheResource}
+ * <li class='jc'>{@link MustacheMixin}
* <li class='jc'>{@link MustacheViewRenderer}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MustacheViewSupport">Mustache View Support</a>
* </ul>
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheViewRenderer.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheViewRenderer.java
index bbe8ea1011..50946589a7 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheViewRenderer.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/MustacheViewRenderer.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.view.*;
* configured {@link MustacheFactory} to render them directly onto the response writer.
*
* <p>
- * Auto-registered by {@link BasicMustacheResource} via
+ * Auto-registered by {@link MustacheMixin} via
* {@link org.apache.juneau.rest.annotation.Rest#responseProcessors() @Rest(responseProcessors=...)}
* — callers who add the mixin don't need to wire up this class explicitly. Callers who want
* to handle {@code MustacheView} returns <i>without</i> adopting the mixin can add this class to
@@ -42,7 +42,7 @@ import org.apache.juneau.rest.view.*;
* <ol class='spaced-list'>
* <li>Inspect the response content. If the value is not a {@link MustacheView}, return
* {@link ResponseProcessor#NEXT NEXT} so the rest of the chain runs.
- * <li>Read the active {@link BasicMustacheResource} from the {@code RestContext} bean store to
+ * <li>Read the active {@link MustacheMixin} from the {@code RestContext} bean store to
* discover the {@link MustacheFactory} (lazy default if no factory bean is registered) and
* the optional template-suffix knob.
* <li>Apply every entry from {@link MustacheView#getResponseHeaders()} via
@@ -59,7 +59,7 @@ import org.apache.juneau.rest.view.*;
* </ol>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicMustacheResource}
+ * <li class='jc'>{@link MustacheMixin}
* <li class='jc'>{@link MustacheView}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/MustacheViewSupport">Mustache View Support</a>
@@ -99,11 +99,11 @@ public class MustacheViewRenderer implements ViewRenderer {
return NEXT;
// Resolve the bridge resource (carries MustacheFactory + cached default + templateSuffix).
- // Fall back to a fresh BasicMustacheResource when the renderer is used standalone without
+ // Fall back to a fresh MustacheMixin when the renderer is used standalone without
// the mixin.
var bridge = req.getContext().getBeanStore()
- .getBean(BasicMustacheResource.class)
- .orElseGet(BasicMustacheResource::new);
+ .getBean(MustacheMixin.class)
+ .orElseGet(MustacheMixin::new);
// Apply caller-supplied response headers first so a caller-provided Content-Type wins
// over the bridge's default below.
diff --git a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/package-info.java b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/package-info.java
index 858131def7..bbddfbe6ac 100644
--- a/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/package-info.java
+++ b/juneau-rest/juneau-rest-server-view-mustache/src/main/java/org/apache/juneau/rest/view/mustache/package-info.java
@@ -22,7 +22,7 @@
* templates via <a href="https://github.com/spullara/mustache.java">mustache.java</a>:
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.view.mustache.BasicMustacheResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.view.mustache.MustacheMixin} —
* mixin that renders raw Mustache templates from the importer's classpath under
* {@code /mustache/*} and auto-registers
* {@link org.apache.juneau.rest.view.mustache.MustacheViewRenderer}.
@@ -40,11 +40,11 @@
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicMustacheResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=MustacheMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicMustacheResource mustache() {
- * <jk>return</jk> BasicMustacheResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> MustacheMixin mustache() {
+ * <jk>return</jk> MustacheMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .templateSuffix(<js>".mustache"</js>)
* .build();
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafResource.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafMixin.java
similarity index 93%
rename from juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafResource.java
rename to juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafMixin.java
index 2d88060a08..4302b2df3a 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafResource.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafMixin.java
@@ -35,7 +35,7 @@ import org.thymeleaf.templateresolver.*;
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicThymeleafResource.class)}; the host then:
+ * {@link Rest#mixins() @Rest(mixins=ThymeleafMixin.class)}; the host then:
*
* <ol class='spaced-list'>
* <li>Gains a default mount at {@code /thymeleaf/*} that serves raw {@code .html} templates from
@@ -51,11 +51,11 @@ import org.thymeleaf.templateresolver.*;
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicThymeleafResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=ThymeleafMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicThymeleafResource thymeleaf() {
- * <jk>return</jk> BasicThymeleafResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> ThymeleafMixin thymeleaf() {
+ * <jk>return</jk> ThymeleafMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .build();
* }
@@ -118,9 +118,9 @@ import org.thymeleaf.templateresolver.*;
*
* <p>
* A host with {@code /templates/} and {@code /admin/templates/} template trees registers two
- * {@code BasicThymeleafResource} beans, each mounted via a subclass declaring its own op-level
+ * {@code ThymeleafMixin} beans, each mounted via a subclass declaring its own op-level
* {@code @RestGet(path=...)} override and its own {@code basePath}. See the
- * {@code BasicThymeleafResource_MockRest_Test} test in {@code juneau-utest} for the canonical
+ * {@code ThymeleafMixin_MockRest_Test} test in {@code juneau-utest} for the canonical
* pattern.
*
* <h5 class='section'>OpenAPI surface:</h5>
@@ -142,7 +142,7 @@ import org.thymeleaf.templateresolver.*;
@Rest(
responseProcessors={ThymeleafViewRenderer.class}
)
-public class BasicThymeleafResource implements RawTemplateDispatcher {
+public class ThymeleafMixin implements RawTemplateDispatcher {
/** Default base path applied when no {@link Builder#basePath(String)} call has been made. */
public static final String DEFAULT_BASE_PATH = "/";
@@ -178,9 +178,9 @@ public class BasicThymeleafResource implements RawTemplateDispatcher {
*
* <p>
* The mixin walk falls back to this constructor when the {@link org.apache.juneau.commons.inject.BeanStore
- * BeanStore} does not have a registered {@code BasicThymeleafResource} bean.
+ * BeanStore} does not have a registered {@code ThymeleafMixin} bean.
*/
- public BasicThymeleafResource() {
+ public ThymeleafMixin() {
this(create());
}
@@ -189,7 +189,7 @@ public class BasicThymeleafResource implements RawTemplateDispatcher {
*
* @param builder The builder. Must not be {@code null}.
*/
- protected BasicThymeleafResource(Builder builder) {
+ protected ThymeleafMixin(Builder builder) {
basePath = builder.basePath;
cacheTemplates = builder.cacheTemplates;
templateMode = builder.templateMode;
@@ -391,7 +391,7 @@ public class BasicThymeleafResource implements RawTemplateDispatcher {
}
/**
- * Builder for {@link BasicThymeleafResource}.
+ * Builder for {@link ThymeleafMixin}.
*/
public static class Builder {
@@ -399,18 +399,18 @@ public class BasicThymeleafResource implements RawTemplateDispatcher {
private boolean cacheTemplates = DEFAULT_CACHE_TEMPLATES;
private TemplateMode templateMode = DEFAULT_TEMPLATE_MODE;
- /** Constructor — package access for {@link BasicThymeleafResource#create()}. */
+ /** Constructor — package access for {@link ThymeleafMixin#create()}. */
protected Builder() {}
/**
* Sets the classpath base path under which template resources are resolved.
*
* <p>
- * Defaults to {@link BasicThymeleafResource#DEFAULT_BASE_PATH "/"}. A typical configured
+ * Defaults to {@link ThymeleafMixin#DEFAULT_BASE_PATH "/"}. A typical configured
* value is {@code "/templates/"} — the Spring-Boot-compatible layout convention.
*
* @param value The base path. {@code null} or blank values reset to the default
- * {@link BasicThymeleafResource#DEFAULT_BASE_PATH}.
+ * {@link ThymeleafMixin#DEFAULT_BASE_PATH}.
* @return This object.
*/
public Builder basePath(String value) {
@@ -480,14 +480,14 @@ public class BasicThymeleafResource implements RawTemplateDispatcher {
}
/**
- * Builds the {@link BasicThymeleafResource}.
+ * Builds the {@link ThymeleafMixin}.
*
- * @return A new {@link BasicThymeleafResource} instance.
+ * @return A new {@link ThymeleafMixin} instance.
*/
- public BasicThymeleafResource build() {
+ public ThymeleafMixin build() {
if (basePath == null)
throw illegalArg("basePath must not be null");
- return new BasicThymeleafResource(this);
+ return new ThymeleafMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafResource.java
similarity index 52%
copy from juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java
copy to juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafResource.java
index d2c5ee349c..214f575854 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafResource.java
@@ -20,55 +20,48 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicThymeleafResource} mixin.
+ * Child-resource flavor of the {@link ThymeleafMixin} mixin.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /thymeleaf/*} and renders raw Thymeleaf
- * templates by delegating to a shared {@link BasicThymeleafResource} instance — the same
- * {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
- *
- * <p>
- * Whereas the {@link BasicThymeleafResource} mixin pins its op at {@code /thymeleaf/*} for
- * composition into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/thymeleaf/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=ThymeleafResource.class)}
+ * under a parent at the subtree {@code /thymeleaf} and renders raw Thymeleaf templates by delegating to a
+ * shared {@link ThymeleafMixin} instance — the same {@link RawTemplateDispatcher} implementation the
+ * mixin and {@link ThymeleafServlet servlet} flavors use, so the three forms cannot drift.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicThymeleafResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link ThymeleafMixin}
+ * <li class='jc'>{@link ThymeleafServlet}
+ * <li class='jc'>{@link ViewResource}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ThymeleafViewSupport">Thymeleaf View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
@Rest(
- paths="/thymeleaf/*",
+ path="/thymeleaf",
responseProcessors={ThymeleafViewRenderer.class}
)
-public class BasicThymeleafServlet extends BasicViewServlet {
-
- private static final long serialVersionUID = 1L;
+public class ThymeleafResource extends ViewResource {
- private final transient BasicThymeleafResource delegate;
+ private final transient ThymeleafMixin delegate;
- /** No-arg constructor — uses a default {@link BasicThymeleafResource} delegate. */
- public BasicThymeleafServlet() {
- this(BasicThymeleafResource.create().build());
+ /** No-arg constructor — uses a default {@link ThymeleafMixin} delegate. */
+ public ThymeleafResource() {
+ this(ThymeleafMixin.create().build());
}
/**
* Delegate constructor.
*
- * @param delegate The shared Thymeleaf renderer/mixin this servlet delegates raw dispatch to.
- * Must not be {@code null}.
+ * @param delegate The shared Thymeleaf renderer/mixin this child delegates raw dispatch to. Must
+ * not be {@code null}.
*/
- protected BasicThymeleafServlet(BasicThymeleafResource delegate) {
+ protected ThymeleafResource(ThymeleafMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewResource */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafServlet.java
similarity index 73%
rename from juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java
rename to juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafServlet.java
index d2c5ee349c..7ce236b9d7 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/BasicThymeleafServlet.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafServlet.java
@@ -20,22 +20,22 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.view.*;
/**
- * Standalone servlet companion of the {@link BasicThymeleafResource} mixin.
+ * Standalone servlet companion of the {@link ThymeleafMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /thymeleaf/*} and renders raw Thymeleaf
- * templates by delegating to a shared {@link BasicThymeleafResource} instance — the same
+ * templates by delegating to a shared {@link ThymeleafMixin} instance — the same
* {@link RawTemplateDispatcher} implementation the mixin uses, so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicThymeleafResource} mixin pins its op at {@code /thymeleaf/*} for
+ * Whereas the {@link ThymeleafMixin} mixin pins its op at {@code /thymeleaf/*} for
* composition into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/thymeleaf/*")}) and inherits the {@code /*} op from
- * {@link BasicViewServlet}.
+ * {@link ViewServlet}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicThymeleafResource}
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link ThymeleafMixin}
+ * <li class='jc'>{@link ViewServlet}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ThymeleafViewSupport">Thymeleaf View Support</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
@@ -47,15 +47,15 @@ import org.apache.juneau.rest.view.*;
paths="/thymeleaf/*",
responseProcessors={ThymeleafViewRenderer.class}
)
-public class BasicThymeleafServlet extends BasicViewServlet {
+public class ThymeleafServlet extends ViewServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicThymeleafResource delegate;
+ private final transient ThymeleafMixin delegate;
- /** No-arg constructor — uses a default {@link BasicThymeleafResource} delegate. */
- public BasicThymeleafServlet() {
- this(BasicThymeleafResource.create().build());
+ /** No-arg constructor — uses a default {@link ThymeleafMixin} delegate. */
+ public ThymeleafServlet() {
+ this(ThymeleafMixin.create().build());
}
/**
@@ -64,11 +64,11 @@ public class BasicThymeleafServlet extends BasicViewServlet {
* @param delegate The shared Thymeleaf renderer/mixin this servlet delegates raw dispatch to.
* Must not be {@code null}.
*/
- protected BasicThymeleafServlet(BasicThymeleafResource delegate) {
+ protected ThymeleafServlet(ThymeleafMixin delegate) {
this.delegate = delegate;
}
- @Override /* BasicViewServlet */
+ @Override /* ViewServlet */
protected RawTemplateDispatcher dispatcher() {
return delegate;
}
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafView.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafView.java
index 1270fae79e..62855ddac2 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafView.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafView.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.view.*;
* render a Thymeleaf template.
*
* <p>
- * Companion to {@link BasicThymeleafResource} and {@link ThymeleafViewRenderer}: the mixin sets up
+ * Companion to {@link ThymeleafMixin} and {@link ThymeleafViewRenderer}: the mixin sets up
* the {@code /thymeleaf/*} mount and registers the renderer; the renderer detects
* {@code ThymeleafView} returns in the response-processor chain and asks the configured
* {@code org.thymeleaf.TemplateEngine} to {@code process(templateName, context, writer)} directly
@@ -60,7 +60,7 @@ import org.apache.juneau.rest.view.*;
* singleton built once and returned from many handlers).
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicThymeleafResource}
+ * <li class='jc'>{@link ThymeleafMixin}
* <li class='jc'>{@link ThymeleafViewRenderer}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ThymeleafViewSupport">Thymeleaf View Support</a>
* </ul>
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafViewRenderer.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafViewRenderer.java
index 79b0467e59..b4ceaa3e44 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafViewRenderer.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/ThymeleafViewRenderer.java
@@ -30,7 +30,7 @@ import org.thymeleaf.context.*;
* configured {@link TemplateEngine} to render them directly onto the response writer.
*
* <p>
- * Auto-registered by {@link BasicThymeleafResource} via
+ * Auto-registered by {@link ThymeleafMixin} via
* {@link org.apache.juneau.rest.annotation.Rest#responseProcessors() @Rest(responseProcessors=...)}
* — callers who add the mixin don't need to wire up this class explicitly. Callers who want
* to handle {@code ThymeleafView} returns <i>without</i> adopting the mixin can add this class to
@@ -42,7 +42,7 @@ import org.thymeleaf.context.*;
* <ol class='spaced-list'>
* <li>Inspect the response content. If the value is not a {@link ThymeleafView}, return
* {@link ResponseProcessor#NEXT NEXT} so the rest of the chain runs.
- * <li>Read the active {@link BasicThymeleafResource} from the {@code RestContext} bean store to
+ * <li>Read the active {@link ThymeleafMixin} from the {@code RestContext} bean store to
* discover the {@link TemplateEngine} (lazy default if no engine bean is registered).
* <li>Build a Thymeleaf {@link Context} populated with the view's attribute map.
* <li>Apply every entry from {@link ThymeleafView#getResponseHeaders()} via
@@ -58,7 +58,7 @@ import org.thymeleaf.context.*;
* </ol>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicThymeleafResource}
+ * <li class='jc'>{@link ThymeleafMixin}
* <li class='jc'>{@link ThymeleafView}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ResponseProcessors">Response Processors</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/ThymeleafViewSupport">Thymeleaf View Support</a>
@@ -96,10 +96,10 @@ public class ThymeleafViewRenderer implements ViewRenderer {
return NEXT;
// Resolve the bridge resource (carries TemplateEngine + cached default). Fall back to a
- // fresh BasicThymeleafResource when the renderer is used standalone without the mixin.
+ // fresh ThymeleafMixin when the renderer is used standalone without the mixin.
var bridge = req.getContext().getBeanStore()
- .getBean(BasicThymeleafResource.class)
- .orElseGet(BasicThymeleafResource::new);
+ .getBean(ThymeleafMixin.class)
+ .orElseGet(ThymeleafMixin::new);
// Apply caller-supplied response headers first so a caller-provided Content-Type wins
// over the bridge's default below.
diff --git a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/package-info.java b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/package-info.java
index c0c196a17f..258f97ff41 100644
--- a/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/package-info.java
+++ b/juneau-rest/juneau-rest-server-view-thymeleaf/src/main/java/org/apache/juneau/rest/view/thymeleaf/package-info.java
@@ -22,7 +22,7 @@
* templates:
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.view.thymeleaf.BasicThymeleafResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.view.thymeleaf.ThymeleafMixin} —
* mixin that renders raw {@code .html} templates from the importer's classpath under
* {@code /thymeleaf/*} and auto-registers
* {@link org.apache.juneau.rest.view.thymeleaf.ThymeleafViewRenderer}.
@@ -40,11 +40,11 @@
* <h5 class='figure'>Composition example (microservice):</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicThymeleafResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=ThymeleafMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
- * <ja>@Bean</ja> BasicThymeleafResource thymeleaf() {
- * <jk>return</jk> BasicThymeleafResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> ThymeleafMixin thymeleaf() {
+ * <jk>return</jk> ThymeleafMixin.<jsm>create</jsm>()
* .basePath(<js>"/templates/"</js>)
* .build();
* }
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 ac854c12c5..3a4bfcf601 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
@@ -516,7 +516,7 @@ public class RestContext extends Context {
* (which is only meaningful inside the {@link RestContext} constructor):
* <ol>
* <li>The resource's {@code getPaths()} virtual getter (defined on {@code RestServlet} /
- * {@code RestObject}). {@code null} return falls through; non-{@code null} (including empty array) wins.
+ * {@code RestResource}). {@code null} return falls through; non-{@code null} (including empty array) wins.
* <li>{@link Rest#paths() @Rest(paths)} annotation default on the most-derived class, SVL-resolved per
* element and comma-split. A {@code VarResolver} is looked up on {@code store} (when present); SVL
* variables like {@code $C{key}} resolve against beans visible to the bean store.
@@ -542,7 +542,7 @@ public class RestContext extends Context {
}
private static String[] resolvePathsCore(List<AnnotationInfo<Rest>> annotations, Object resource, VarResolver vr, WritableBeanStore beanStore) {
- // Rung 2: getPaths() virtual getter on the resource (RestServlet / RestObject / any matching class).
+ // Rung 2: getPaths() virtual getter on the resource (RestServlet / RestResource / any matching class).
// The getter return is normalized to a flat List<String> of raw leaves (any String / String[] /
// Collection / Iterable / Stream / nested mix of those), then each leaf flows through the same
// SVL-resolve + comma-split pipeline used for @Rest(paths=...) annotation elements.
@@ -637,7 +637,7 @@ public class RestContext extends Context {
/**
* Reflectively invokes a no-arg {@code getPaths()} method on the resource (defined on
* {@link org.apache.juneau.rest.servlet.RestServlet RestServlet} and
- * {@link org.apache.juneau.rest.servlet.RestObject RestObject}). Reflection is used to avoid coupling this
+ * {@link org.apache.juneau.rest.servlet.RestResource RestResource}). Reflection is used to avoid coupling this
* static utility to either base class — if a custom {@code @Rest}-annotated POJO declares
* {@code public Object getPaths()} (or any covariant return type such as {@code String[]},
* {@code List<String>}, etc.), it participates uniformly.
@@ -3400,7 +3400,7 @@ public class RestContext extends Context {
* <li><b>Programmatic</b> — {@link Builder#paths(String...)} setter (or {@link Args#paths()} record
* field). Highest precedence; an empty array (not {@code null}) explicitly clears the mount list.
* <li><b>Getter</b> — the resource's {@code getPaths()} virtual method (defined on
- * {@code RestServlet} and {@code RestObject}). {@code null} return inherits; non-{@code null} (including
+ * {@code RestServlet} and {@code RestResource}). {@code null} return inherits; non-{@code null} (including
* empty array) wins over the annotation default.
* <li><b>Annotation default</b> — {@link Rest#paths()}, walked top-down across the resource-class
* hierarchy with the most-derived non-empty value winning. Each element is
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
index 82350d3519..7ad92a9255 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -135,7 +135,6 @@ import jakarta.servlet.http.*;
* </ul>
* <li>Methods for accessing static files:
* <ul class='javatreec'>
- * <li class='jm'>{@link RestRequest#getStaticFiles() getStaticFiles()}
* <li class='jm'>{@link RestRequest#getVarResolverSession() getVarResolverSession()}
* </ul>
* <li>Methods for assertions:
@@ -1395,16 +1394,6 @@ public class RestRequest extends HttpServletRequestWrapper {
return cp == null || ! sp.startsWith(cp) ? sp : sp.substring(cp.length());
}
- /**
- * Returns the static files registered on the REST resource context object.
- *
- * <p>
- * Used to retrieve localized files to be served up as static files through the REST API.
- *
- * @return This object.
- */
- public StaticFiles getStaticFiles() { return context.getStaticFiles(); }
-
/**
* Returns the localized swagger associated with the resource.
*
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
index 921a408658..a35b6573de 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/Rest.java
@@ -448,7 +448,7 @@ public @interface Rest {
* {@code "debugEnablement"}, {@code "debugDefault"}, {@code "partSerializer"}, {@code "partParser"}, and
* {@code "messages"}. For example, {@code @Rest(noInherit={"guards"})} on a mixin removes the host's guard
* chain from the mixin's endpoints (typical pattern for deliberately-unguarded probes like
- * {@code BasicHealthResource}).
+ * {@code HealthMixin}).
*
* <h5 class='section'>See Also:</h5><ul>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/SessionOptions">Session Options</a>
@@ -1589,7 +1589,7 @@ public @interface Rest {
* Used to retrieve localized files to be served up as static files through the REST API via the following
* predefined methods:
* <ul class='javatree'>
- * <li class='jm'>{@link BasicRestObject#getHtdoc(String, Locale)}.
+ * <li class='jm'>{@link BasicRestResource#getHtdoc(String, Locale)}.
* <li class='jm'>{@link BasicRestServlet#getHtdoc(String, Locale)}.
* </ul>
*
@@ -1597,7 +1597,6 @@ public @interface Rest {
* The static file finder can be accessed through the following methods:
* <ul class='javatree'>
* <li class='jm'>{@link RestContext#getStaticFiles()}
- * <li class='jm'>{@link RestRequest#getStaticFiles()}
* </ul>
*
* <h5 class='section'>Inheritance Rules</h5>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/ChildResourceDescriptions.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/ChildResourceDescriptions.java
index 6202117368..f76484933c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/ChildResourceDescriptions.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/beans/ChildResourceDescriptions.java
@@ -31,8 +31,7 @@ import org.apache.juneau.rest.servlet.*;
*
* <h5 class='section'>See Also:</h5><ul>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/UtilityBeans">Utility Beans</a>
- * <li class='jic'>{@link BasicGroupOperations}
-
+ * <li class='jc'>{@link org.apache.juneau.rest.servlet.BasicRestServletGroup}
* </ul>
*
* @serial exclude
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJson5Config.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJson5Config.java
index 87b7112159..030436aaf6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJson5Config.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJson5Config.java
@@ -68,7 +68,7 @@ import org.apache.juneau.serializer.annotation.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicJson5Config { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicJson5Config { ... }
* </p>
*
* <p>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonConfig.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonConfig.java
index fe80458596..6d713f8a21 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonConfig.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonConfig.java
@@ -71,7 +71,7 @@ import org.apache.juneau.serializer.annotation.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicJsonConfig { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicJsonConfig { ... }
* </p>
*
* <p>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonHtmlConfig.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonHtmlConfig.java
index e0ca14386b..341c134eda 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonHtmlConfig.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicJsonHtmlConfig.java
@@ -85,7 +85,7 @@ import org.apache.juneau.serializer.annotation.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicJsonHtmlConfig { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicJsonHtmlConfig { ... }
* </p>
*
* <p>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiConfig.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiConfig.java
index 1bde4e3aa2..36f69040f0 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiConfig.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicOpenApiConfig.java
@@ -68,7 +68,7 @@ import org.apache.juneau.serializer.annotation.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicOpenApiConfig { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicOpenApiConfig { ... }
* </p>
*
* <p>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalConfig.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalConfig.java
index acf496d595..03d56cfc91 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalConfig.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/config/BasicUniversalConfig.java
@@ -122,7 +122,7 @@ import org.apache.juneau.xml.*;
* <p class='bjava'>
* <jc>// Used on a child resource.</jc>
* <ja>@Rest</ja>
- * <jk>public class</jk> MyResource <jk>extends</jk> RestObject <jk>implements</jk> BasicUniversalConfig { ... }
+ * <jk>public class</jk> MyResource <jk>extends</jk> RestResource <jk>implements</jk> BasicUniversalConfig { ... }
* </p>
*
* <p>
@@ -135,8 +135,8 @@ import org.apache.juneau.xml.*;
* <ul class='javatreec'>
* <li class='jc'>{@link BasicRestServlet}
* <li class='jc'>{@link BasicRestServletGroup}
- * <li class='jc'>{@link BasicRestObject}
- * <li class='jc'>{@link BasicRestObjectGroup}
+ * <li class='jc'>{@link BasicRestResource}
+ * <li class='jc'>{@link BasicRestResourceGroup}
* </ul>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestAnnotatedClassBasics">@Rest-Annotated Class Basics</a>
* </ul>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicFaviconResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconMixin.java
similarity index 82%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicFaviconResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconMixin.java
index cce1f5e64f..0e4170c371 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicFaviconResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconMixin.java
@@ -30,21 +30,21 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that serves a {@code favicon.ico} icon at {@code /favicon.ico}.
*
* <p>
- * Sibling of {@link BasicSeoResource} (robots.txt / sitemap.xml), {@link BasicVersionResource}
- * ({@code /version} / {@code /info} / {@code /about}), and {@link BasicWellKnownResource}
+ * Sibling of {@link SeoMixin} (robots.txt / sitemap.xml), {@link VersionMixin}
+ * ({@code /version} / {@code /info} / {@code /about}), and {@link WellKnownMixin}
* ({@code /.well-known/*}). All four classes live in the {@code org.apache.juneau.rest.convention}
* convention-endpoints mixin pack.
*
* <p>
- * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=BasicFaviconResource.class)};
+ * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=FaviconMixin.class)};
* the {@code /favicon.ico} URL becomes available alongside the host's own endpoints with no further
* wiring.
*
* <h5 class='section'>Hardcoded mount path:</h5>
*
* <p>
- * Unlike the sibling api-docs and ops mixins (see {@link BasicSwaggerResource},
- * {@link BasicVersionResource}, etc.) the mount path here is <b>not</b> SVL-configurable
+ * Unlike the sibling api-docs and ops mixins (see {@link SwaggerMixin},
+ * {@link VersionMixin}, etc.) the mount path here is <b>not</b> SVL-configurable
* — {@code /favicon.ico} is fixed by browser convention and the {@code link rel="icon"}
* default the HTML spec inherits from <a href="https://html.spec.whatwg.org/multipage/links.html#rel-icon">WHATWG HTML</a>.
* Browsers fetch {@code /favicon.ico} from the site root regardless of any application-level
@@ -61,14 +61,14 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicFaviconResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=FaviconMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
* <jc>// Use the default Juneau-branded favicon.</jc>
* }
*
* <jc>// Or override the icon bytes via a @Bean factory:</jc>
- * <ja>@Bean BasicFaviconResource favicon()</ja> {
- * <jk>return</jk> BasicFaviconResource.<jsm>create</jsm>().bytes(myLogoBytes).build();
+ * <ja>@Bean FaviconMixin favicon()</ja> {
+ * <jk>return</jk> FaviconMixin.<jsm>create</jsm>().bytes(myLogoBytes).build();
* }
* </p>
*
@@ -80,7 +80,7 @@ import org.apache.juneau.rest.annotation.*;
* (30 days — favicons rarely change and browsers re-fetch frequently when uncached).
* <li>The default icon ({@code juneau-favicon.ico} on the framework classpath) is a
* 16×16 Juneau-branded ICO; users replace it by registering an alternate
- * {@code @Bean BasicFaviconResource} whose builder supplies different bytes.
+ * {@code @Bean FaviconMixin} whose builder supplies different bytes.
* <li>The handler is excluded from generated Swagger / OpenAPI specs via
* {@link OpSwagger#ignore() @OpSwagger(ignore=true)} — favicons are not
* API-meaningful.
@@ -92,15 +92,15 @@ import org.apache.juneau.rest.annotation.*;
* <li>{@link #create() create()} — entry point for configuring an instance.
* <li>{@link Builder#bytes(byte[]) bytes(byte[])} — raw favicon bytes.
* <li>{@link Builder#classpath(String) classpath(String)} — load icon bytes from a
- * classpath resource (resolved against the {@code BasicFaviconResource} classloader).
+ * classpath resource (resolved against the {@code FaviconMixin} classloader).
* <li>{@link Builder#cacheControl(String) cacheControl(String)} — override the default
* 30-day {@code Cache-Control} header.
* </ul>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicSeoResource}
- * <li class='jc'>{@link BasicVersionResource}
- * <li class='jc'>{@link BasicWellKnownResource}
+ * <li class='jc'>{@link SeoMixin}
+ * <li class='jc'>{@link VersionMixin}
+ * <li class='jc'>{@link WellKnownMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -108,7 +108,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicFaviconResource {
+public class FaviconMixin {
/** Default {@code Cache-Control} header value: {@code max-age=2592000, public} (30 days). */
public static final String DEFAULT_CACHE_CONTROL = "max-age=2592000, public";
@@ -117,7 +117,7 @@ public class BasicFaviconResource {
private static final String DEFAULT_FAVICON_RESOURCE = "/juneau-favicon.ico";
/**
- * Creates a new builder for configuring a {@link BasicFaviconResource}.
+ * Creates a new builder for configuring a {@link FaviconMixin}.
*
* @return A new builder.
*/
@@ -130,10 +130,10 @@ public class BasicFaviconResource {
/**
* No-arg constructor — used when a host registers the mixin without supplying a
- * builder-configured {@code @Bean BasicFaviconResource}. Loads the default Juneau-branded
+ * builder-configured {@code @Bean FaviconMixin}. Loads the default Juneau-branded
* favicon from the classpath.
*/
- public BasicFaviconResource() {
+ public FaviconMixin() {
this(create());
}
@@ -142,7 +142,7 @@ public class BasicFaviconResource {
*
* @param builder The builder.
*/
- protected BasicFaviconResource(Builder builder) {
+ protected FaviconMixin(Builder builder) {
bytes = builder.resolveBytes();
cacheControl = builder.cacheControl;
}
@@ -166,7 +166,7 @@ public class BasicFaviconResource {
}
/**
- * Builder for {@link BasicFaviconResource} instances.
+ * Builder for {@link FaviconMixin} instances.
*/
public static class Builder {
@@ -174,7 +174,7 @@ public class BasicFaviconResource {
private String classpath;
private String cacheControl = DEFAULT_CACHE_CONTROL;
- /** Constructor — package access for {@link BasicFaviconResource#create()}. */
+ /** Constructor — package access for {@link FaviconMixin#create()}. */
protected Builder() {}
/**
@@ -198,7 +198,7 @@ public class BasicFaviconResource {
* Sets the classpath resource path from which to load the favicon bytes.
*
* <p>
- * Resolved via {@link Class#getResourceAsStream(String) BasicFaviconResource.class.getResourceAsStream(...)}
+ * Resolved via {@link Class#getResourceAsStream(String) FaviconMixin.class.getResourceAsStream(...)}
* at {@link #build()} time. A resolved-to-{@code null} stream falls back to the framework's
* default favicon. Mutually exclusive with {@link #bytes(byte[])}.
*
@@ -227,12 +227,12 @@ public class BasicFaviconResource {
}
/**
- * Builds a {@link BasicFaviconResource} instance.
+ * Builds a {@link FaviconMixin} instance.
*
* @return A configured instance.
*/
- public BasicFaviconResource build() {
- return new BasicFaviconResource(this);
+ public FaviconMixin build() {
+ return new FaviconMixin(this);
}
byte[] resolveBytes() {
@@ -249,7 +249,7 @@ public class BasicFaviconResource {
}
private static byte[] readClasspath(String path) {
- try (var in = BasicFaviconResource.class.getResourceAsStream(path)) {
+ try (var in = FaviconMixin.class.getResourceAsStream(path)) {
if (in == null)
return null;
return in.readAllBytes();
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconResource.java
new file mode 100644
index 0000000000..a20ccc2cac
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconResource.java
@@ -0,0 +1,74 @@
+/*
+ * 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.rest.convention;
+
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Child-resource flavor of the {@link FaviconMixin} mixin.
+ *
+ * <p>
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=FaviconResource.class)}
+ * under a parent at the subtree {@code /favicon.ico} and serves the configured favicon bytes by
+ * delegating to a shared {@link FaviconMixin} instance — so the forms cannot drift.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link FaviconMixin}
+ * <li class='jc'>{@link FaviconServlet}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+// @formatter:off
+@Rest(path="/favicon.ico")
+public class FaviconResource extends RestResource {
+
+ private final transient FaviconMixin delegate;
+
+ /** No-arg constructor — uses a default {@link FaviconMixin} delegate. */
+ public FaviconResource() {
+ this(new FaviconMixin());
+ }
+
+ /**
+ * Delegate constructor.
+ *
+ * @param delegate The shared favicon mixin this child delegates to. Must not be {@code null}.
+ */
+ protected FaviconResource(FaviconMixin delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * [GET /*] — serve the configured favicon bytes.
+ *
+ * @return The favicon as an {@link HttpResource} with proper headers.
+ */
+ @RestGet(
+ path="/*",
+ summary="Favorites icon",
+ description="Browser favorites icon (favicon.ico).",
+ swagger=@OpSwagger(ignore=true)
+ )
+ public HttpResource getFavicon() {
+ return delegate.getFavicon();
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconServlet.java
new file mode 100644
index 0000000000..82a1cfc769
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/FaviconServlet.java
@@ -0,0 +1,86 @@
+/*
+ * 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.rest.convention;
+
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Standalone servlet companion of the {@link FaviconMixin} mixin.
+ *
+ * <p>
+ * Mounts as a <b>sibling top-level servlet</b> at {@code /favicon.ico} and serves the configured favicon
+ * bytes by delegating to a shared {@link FaviconMixin} instance — the same logic the mixin uses,
+ * so the two forms cannot drift. Browsers fetch {@code /favicon.ico} from the site root, so a standalone
+ * servlet at that fixed path is the natural deployment for sites that do not compose the mixin into an
+ * existing host resource.
+ *
+ * <h5 class='figure'>Microservice registration:</h5>
+ *
+ * <p class='bjava'>
+ * <ja>@Bean</ja> Servlet favicon() {
+ * <jk>return new</jk> FaviconServlet(); <jc>// auto-mounted at /favicon.ico</jc>
+ * }
+ * </p>
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link FaviconMixin}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @serial exclude
+ * @since 9.5.0
+ */
+// @formatter:off
+@Rest(paths="/favicon.ico")
+public class FaviconServlet extends RestServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private final transient FaviconMixin delegate;
+
+ /** No-arg constructor — uses a default {@link FaviconMixin} delegate. */
+ public FaviconServlet() {
+ this(new FaviconMixin());
+ }
+
+ /**
+ * Delegate constructor.
+ *
+ * @param delegate The shared favicon mixin this servlet delegates to. Must not be {@code null}.
+ */
+ protected FaviconServlet(FaviconMixin delegate) {
+ this.delegate = delegate;
+ }
+
+ /**
+ * [GET /*] — serve the configured favicon bytes.
+ *
+ * @return The favicon as an {@link HttpResource} with proper headers.
+ */
+ @RestGet(
+ path="/*",
+ summary="Favorites icon",
+ description="Browser favorites icon (favicon.ico).",
+ swagger=@OpSwagger(ignore=true)
+ )
+ public HttpResource getFavicon() {
+ return delegate.getFavicon();
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicSeoResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/SeoMixin.java
similarity index 90%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicSeoResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/SeoMixin.java
index 34e43b0c1d..f09d0e6776 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicSeoResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/SeoMixin.java
@@ -28,21 +28,21 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that serves SEO-conventional endpoints {@code /robots.txt} and {@code /sitemap.xml}.
*
* <p>
- * Sibling of {@link BasicFaviconResource} ({@code /favicon.ico}),
- * {@link BasicVersionResource} ({@code /version} / {@code /info} / {@code /about}), and
- * {@link BasicWellKnownResource} ({@code /.well-known/*}). All four classes live in the
+ * Sibling of {@link FaviconMixin} ({@code /favicon.ico}),
+ * {@link VersionMixin} ({@code /version} / {@code /info} / {@code /about}), and
+ * {@link WellKnownMixin} ({@code /.well-known/*}). All four classes live in the
* {@code org.apache.juneau.rest.convention} convention-endpoints mixin pack.
*
* <p>
- * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=BasicSeoResource.class)};
+ * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=SeoMixin.class)};
* the {@code /robots.txt} and {@code /sitemap.xml} URLs become available alongside the host's own
* endpoints with no further wiring.
*
* <h5 class='section'>Hardcoded mount paths:</h5>
*
* <p>
- * Unlike the sibling api-docs and ops mixins (see {@link BasicSwaggerResource},
- * {@link BasicVersionResource}, etc.), the two mount paths here are <b>not</b> SVL-configurable.
+ * Unlike the sibling api-docs and ops mixins (see {@link SwaggerMixin},
+ * {@link VersionMixin}, etc.), the two mount paths here are <b>not</b> SVL-configurable.
* {@code /robots.txt} is fixed by the Robots Exclusion Protocol
* (<a href="https://www.rfc-editor.org/rfc/rfc9309">RFC 9309</a>) which prescribes that
* crawlers fetch the policy from {@code /robots.txt} at the site root; {@code /sitemap.xml} is
@@ -62,12 +62,12 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicSeoResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=SeoMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { }
*
* <jc>// Override defaults via a @Bean factory:</jc>
- * <ja>@Bean</ja> BasicSeoResource seo() {
- * <jk>return</jk> BasicSeoResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> SeoMixin seo() {
+ * <jk>return</jk> SeoMixin.<jsm>create</jsm>()
* .robotsAllow(<js>"*"</js>, <js>"/"</js>)
* .sitemapEntry(<js>"/api/items"</js>)
* .build();
@@ -94,9 +94,9 @@ import org.apache.juneau.rest.annotation.*;
* </ul>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFaviconResource}
- * <li class='jc'>{@link BasicVersionResource}
- * <li class='jc'>{@link BasicWellKnownResource}
+ * <li class='jc'>{@link FaviconMixin}
+ * <li class='jc'>{@link VersionMixin}
+ * <li class='jc'>{@link WellKnownMixin}
* <li class='link'><a class="doclink" href="https://www.rfc-editor.org/rfc/rfc9309">RFC 9309 — Robots Exclusion Protocol</a>
* <li class='link'><a class="doclink" href="https://www.sitemaps.org/protocol.html">sitemaps.org — Sitemap protocol</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
@@ -106,7 +106,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicSeoResource {
+public class SeoMixin {
/** Default robots policy: deny everything. */
public static final String DEFAULT_ROBOTS = "User-agent: *\nDisallow: /\n";
@@ -124,7 +124,7 @@ public class BasicSeoResource {
private final List<SitemapEntry> sitemapEntries;
/** No-arg constructor used when a host registers the mixin without builder configuration. */
- public BasicSeoResource() {
+ public SeoMixin() {
this(create());
}
@@ -133,7 +133,7 @@ public class BasicSeoResource {
*
* @param builder The builder.
*/
- protected BasicSeoResource(Builder builder) {
+ protected SeoMixin(Builder builder) {
robotsTxt = builder.buildRobots();
sitemapEntries = List.copyOf(builder.sitemapEntries);
}
@@ -214,7 +214,7 @@ public class BasicSeoResource {
}
/**
- * Builder for {@link BasicSeoResource} instances.
+ * Builder for {@link SeoMixin} instances.
*/
public static class Builder {
@@ -222,7 +222,7 @@ public class BasicSeoResource {
private final List<SitemapEntry> sitemapEntries = new ArrayList<>();
private String customRobotsTxt;
- /** Constructor — package access for {@link BasicSeoResource#create()}. */
+ /** Constructor — package access for {@link SeoMixin#create()}. */
protected Builder() {}
/**
@@ -301,12 +301,12 @@ public class BasicSeoResource {
}
/**
- * Builds a {@link BasicSeoResource} instance.
+ * Builds a {@link SeoMixin} instance.
*
* @return A configured instance.
*/
- public BasicSeoResource build() {
- return new BasicSeoResource(this);
+ public SeoMixin build() {
+ return new SeoMixin(this);
}
String buildRobots() {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionMixin.java
similarity index 89%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionMixin.java
index 4535b93635..c09832447b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionMixin.java
@@ -33,13 +33,13 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that serves deployment-introspection metadata at {@code /version} (configurable).
*
* <p>
- * Sibling of {@link BasicFaviconResource}, {@link BasicSeoResource}, and
- * {@link BasicWellKnownResource}. All four classes live in the
+ * Sibling of {@link FaviconMixin}, {@link SeoMixin}, and
+ * {@link WellKnownMixin}. All four classes live in the
* {@code org.apache.juneau.rest.convention} convention-endpoints mixin pack.
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicVersionResource.class)}; the three URLs become available
+ * {@link Rest#mixins() @Rest(mixins=VersionMixin.class)}; the three URLs become available
* alongside the host's own endpoints with no further wiring.
*
* <h5 class='section'>Configurable mount path:</h5>
@@ -77,13 +77,13 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicVersionResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=VersionMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { }
*
* <jc>// Default behavior reads MANIFEST.MF + git.properties from the importer's classpath.</jc>
* <jc>// Override programmatically via a @Bean factory:</jc>
- * <ja>@Bean</ja> BasicVersionResource version() {
- * <jk>return</jk> BasicVersionResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> VersionMixin version() {
+ * <jk>return</jk> VersionMixin.<jsm>create</jsm>()
* .entry(<js>"name"</js>, <js>"my-app"</js>)
* .entry(<js>"version"</js>, <js>"1.2.3"</js>)
* .build();
@@ -94,7 +94,7 @@ import org.apache.juneau.rest.annotation.*;
*
* <p>
* The default {@link Builder#fromManifest() fromManifest()} reader walks the
- * {@link BasicVersionResource} classloader for {@code /META-INF/MANIFEST.MF} and reads the standard
+ * {@link VersionMixin} classloader for {@code /META-INF/MANIFEST.MF} and reads the standard
* {@code Implementation-Title}, {@code Implementation-Version}, {@code Implementation-Vendor}, and
* {@code Build-Jdk} attributes (lowercased to {@code name}, {@code version}, {@code vendor},
* {@code javaVersion}). The default {@link Builder#fromGitProperties() fromGitProperties()} reader
@@ -106,7 +106,7 @@ import org.apache.juneau.rest.annotation.*;
*
* <p>
* <b>Spring Boot fat-jar caveat:</b> Spring Boot rewrites {@code MANIFEST.MF} during repackaging.
- * The mixin's no-arg-default reader uses {@code BasicVersionResource.class.getClassLoader()};
+ * The mixin's no-arg-default reader uses {@code VersionMixin.class.getClassLoader()};
* users who want the importer's app manifest under a Spring Boot executable jar should register an
* explicit {@link Builder#fromManifest(ClassLoader) fromManifest(importerClassLoader)} call so the
* lookup starts from the importer's classloader rather than the framework's.
@@ -131,9 +131,9 @@ import org.apache.juneau.rest.annotation.*;
* {@link OpSwagger#ignore() @OpSwagger(ignore=true)}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFaviconResource}
- * <li class='jc'>{@link BasicSeoResource}
- * <li class='jc'>{@link BasicWellKnownResource}
+ * <li class='jc'>{@link FaviconMixin}
+ * <li class='jc'>{@link SeoMixin}
+ * <li class='jc'>{@link WellKnownMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -141,7 +141,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicVersionResource {
+public class VersionMixin {
/** Sentinel value returned for entries that the mixin couldn't resolve. */
public static final String UNKNOWN = "(unknown)";
@@ -177,7 +177,7 @@ public class BasicVersionResource {
* directly or via the {@link org.apache.juneau.commons.inject.BeanInstantiator BeanInstantiator}
* builder-detection path.
*/
- public BasicVersionResource() {
+ public VersionMixin() {
this(create());
}
@@ -188,13 +188,13 @@ public class BasicVersionResource {
* Applies the default lookup chain ({@link Builder#fromManifest()} +
* {@link Builder#fromGitProperties()} + {@link Builder#fromJavaVersion()}) when no other
* builder method has been called — ensuring that a freshly-created builder
- * (whether instantiated directly via {@code new BasicVersionResource(create())} or via the
+ * (whether instantiated directly via {@code new VersionMixin(create())} or via the
* {@link org.apache.juneau.commons.inject.BeanInstantiator BeanInstantiator}'s
* builder-detection path) always produces a non-empty payload.
*
* @param builder The builder.
*/
- protected BasicVersionResource(Builder builder) {
+ protected VersionMixin(Builder builder) {
if (! builder.explicit)
builder.fromManifest().fromGitProperties().fromJavaVersion();
info = Collections.unmodifiableMap(new LinkedHashMap<>(builder.entries));
@@ -233,7 +233,7 @@ public class BasicVersionResource {
}
/**
- * Builder for {@link BasicVersionResource} instances.
+ * Builder for {@link VersionMixin} instances.
*/
public static class Builder {
@@ -243,7 +243,7 @@ public class BasicVersionResource {
/**
* Env-driven default for the {@code javaVersion} entry; resolved from the {@code java.version}
* system property (defaulting to the literal {@code (unknown)}, matching
- * {@link BasicVersionResource#UNKNOWN}). Populated by {@link BeanInstantiator} via
+ * {@link VersionMixin#UNKNOWN}). Populated by {@link BeanInstantiator} via
* {@link Value @Value} field injection.
*
* <p>
@@ -254,7 +254,7 @@ public class BasicVersionResource {
@Value("${java.version:(unknown)}")
String javaVersionDefault;
- /** Constructor — protected access for {@link BasicVersionResource#create()}. */
+ /** Constructor — protected access for {@link VersionMixin#create()}. */
protected Builder() {}
/**
@@ -262,7 +262,7 @@ public class BasicVersionResource {
*
* @param key The entry key. Must not be <jk>null</jk> or blank.
* @param value The entry value (a <jk>null</jk> value is recorded as
- * {@link BasicVersionResource#UNKNOWN}).
+ * {@link VersionMixin#UNKNOWN}).
* @return This object.
*/
public Builder entry(String key, String value) {
@@ -275,7 +275,7 @@ public class BasicVersionResource {
* Bulk-set entries from a map.
*
* @param values Entries to add. <jk>null</jk> values are recorded as
- * {@link BasicVersionResource#UNKNOWN}.
+ * {@link VersionMixin#UNKNOWN}.
* @return This object.
*/
public Builder entries(Map<String,String> values) {
@@ -288,16 +288,16 @@ public class BasicVersionResource {
/**
* Reads {@code Implementation-Title}, {@code Implementation-Version},
* {@code Implementation-Vendor}, and {@code Build-Jdk} from
- * {@code /META-INF/MANIFEST.MF} on the {@link BasicVersionResource} classloader.
+ * {@code /META-INF/MANIFEST.MF} on the {@link VersionMixin} classloader.
*
* <p>
- * Missing keys are recorded as {@link BasicVersionResource#UNKNOWN}. A missing
+ * Missing keys are recorded as {@link VersionMixin#UNKNOWN}. A missing
* {@code MANIFEST.MF} resource is silently skipped.
*
* @return This object.
*/
public Builder fromManifest() {
- return fromManifest(BasicVersionResource.class.getClassLoader());
+ return fromManifest(VersionMixin.class.getClassLoader());
}
/**
@@ -306,7 +306,7 @@ public class BasicVersionResource {
* <p>
* Useful under Spring Boot fat jars, where the importer's app manifest is reachable from
* its own classloader but not the framework's. Missing keys are recorded as
- * {@link BasicVersionResource#UNKNOWN}; a missing {@code MANIFEST.MF} resource is silently
+ * {@link VersionMixin#UNKNOWN}; a missing {@code MANIFEST.MF} resource is silently
* skipped.
*
* @param classLoader The classloader to walk.
@@ -350,7 +350,7 @@ public class BasicVersionResource {
/**
* Reads {@code git.commit.id}, {@code git.branch}, and {@code git.build.time} from
- * {@code /git.properties} on the {@link BasicVersionResource} classloader.
+ * {@code /git.properties} on the {@link VersionMixin} classloader.
*
* <p>
* Output of the
@@ -361,7 +361,7 @@ public class BasicVersionResource {
* @return This object.
*/
public Builder fromGitProperties() {
- return fromGitProperties(BasicVersionResource.class.getClassLoader());
+ return fromGitProperties(VersionMixin.class.getClassLoader());
}
/**
@@ -396,7 +396,7 @@ public class BasicVersionResource {
}
/**
- * Builds a {@link BasicVersionResource} instance.
+ * Builds a {@link VersionMixin} instance.
*
* <p>
* The constructor applies the default lookup chain ({@link #fromManifest()} +
@@ -406,8 +406,8 @@ public class BasicVersionResource {
*
* @return A configured instance.
*/
- public BasicVersionResource build() {
- return new BasicVersionResource(this);
+ public VersionMixin build() {
+ return new VersionMixin(this);
}
private static Map<String,String> readManifestAttributes(ClassLoader cl) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionResource.java
similarity index 56%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionResource.java
index 5927252eed..74da413b42 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionResource.java
@@ -24,54 +24,43 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicVersionResource} mixin.
+ * Child-resource flavor of the {@link VersionMixin} version/build-metadata capability.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /version/*} and serves the same
- * deployment-introspection JSON map as the mixin by delegating to a shared
- * {@link BasicVersionResource} instance — so the two forms cannot drift.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=VersionResource.class)}
+ * under a parent at the subtree {@code /version} and serves the same deployment-introspection JSON map
+ * as the mixin by delegating to a shared {@link VersionMixin} instance — so the forms cannot drift.
*
* <p>
- * Whereas the {@link BasicVersionResource} mixin pins its op at {@code /version} for composition
- * into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/version/*")}) and pins the op at {@code /*}.
- *
- * <h5 class='figure'>Microservice registration:</h5>
- *
- * <p class='bjava'>
- * <ja>@Bean</ja> Servlet version() {
- * <jk>return new</jk> BasicVersionServlet(); <jc>// auto-mounted at /version/* by JettyServerComponent</jc>
- * }
- * </p>
+ * Whereas the {@link VersionMixin} mixin pins its op at {@code /version} for composition into a host at
+ * {@code /}, this child declares the subtree at the class level
+ * ({@link Rest#path() @Rest(path="/version")}) and pins the op at {@code /*}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicVersionResource}
+ * <li class='jc'>{@link VersionMixin}
+ * <li class='jc'>{@link VersionServlet}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
// @formatter:off
-@Rest(paths="/version/*")
-public class BasicVersionServlet extends RestServlet {
-
- private static final long serialVersionUID = 1L;
+@Rest(path="/version")
+public class VersionResource extends RestResource {
- private final transient BasicVersionResource delegate;
+ private final transient VersionMixin delegate;
- /** No-arg constructor — uses a default {@link BasicVersionResource} delegate. */
- public BasicVersionServlet() {
- this(new BasicVersionResource());
+ /** No-arg constructor — uses a default {@link VersionMixin} delegate. */
+ public VersionResource() {
+ this(new VersionMixin());
}
/**
* Delegate constructor.
*
- * @param delegate The shared version mixin this servlet delegates to. Must not be
- * {@code null}.
+ * @param delegate The shared version mixin this child delegates to. Must not be {@code null}.
*/
- protected BasicVersionServlet(BasicVersionResource delegate) {
+ protected VersionResource(VersionMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionServlet.java
similarity index 77%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionServlet.java
index 5927252eed..51f9607395 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicVersionServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/VersionServlet.java
@@ -24,15 +24,15 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicVersionResource} mixin.
+ * Standalone servlet companion of the {@link VersionMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /version/*} and serves the same
* deployment-introspection JSON map as the mixin by delegating to a shared
- * {@link BasicVersionResource} instance — so the two forms cannot drift.
+ * {@link VersionMixin} instance — so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicVersionResource} mixin pins its op at {@code /version} for composition
+ * Whereas the {@link VersionMixin} mixin pins its op at {@code /version} for composition
* into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/version/*")}) and pins the op at {@code /*}.
*
@@ -40,12 +40,12 @@ import org.apache.juneau.rest.servlet.*;
*
* <p class='bjava'>
* <ja>@Bean</ja> Servlet version() {
- * <jk>return new</jk> BasicVersionServlet(); <jc>// auto-mounted at /version/* by JettyServerComponent</jc>
+ * <jk>return new</jk> VersionServlet(); <jc>// auto-mounted at /version/* by JettyServerComponent</jc>
* }
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicVersionResource}
+ * <li class='jc'>{@link VersionMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -54,15 +54,15 @@ import org.apache.juneau.rest.servlet.*;
*/
// @formatter:off
@Rest(paths="/version/*")
-public class BasicVersionServlet extends RestServlet {
+public class VersionServlet extends RestServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicVersionResource delegate;
+ private final transient VersionMixin delegate;
- /** No-arg constructor — uses a default {@link BasicVersionResource} delegate. */
- public BasicVersionServlet() {
- this(new BasicVersionResource());
+ /** No-arg constructor — uses a default {@link VersionMixin} delegate. */
+ public VersionServlet() {
+ this(new VersionMixin());
}
/**
@@ -71,7 +71,7 @@ public class BasicVersionServlet extends RestServlet {
* @param delegate The shared version mixin this servlet delegates to. Must not be
* {@code null}.
*/
- protected BasicVersionServlet(BasicVersionResource delegate) {
+ protected VersionServlet(VersionMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicWellKnownResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/WellKnownMixin.java
similarity index 84%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicWellKnownResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/WellKnownMixin.java
index ae339127af..13412ce23e 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/BasicWellKnownResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/WellKnownMixin.java
@@ -27,8 +27,8 @@ import org.apache.juneau.rest.annotation.*;
* {@code /.well-known/*} discovery endpoints.
*
* <p>
- * Sibling of {@link BasicFaviconResource}, {@link BasicSeoResource}, and
- * {@link BasicVersionResource}. All four classes live in the
+ * Sibling of {@link FaviconMixin}, {@link SeoMixin}, and
+ * {@link VersionMixin}. All four classes live in the
* {@code org.apache.juneau.rest.convention} convention-endpoints mixin pack.
*
* <p>
@@ -40,15 +40,15 @@ import org.apache.juneau.rest.annotation.*;
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicWellKnownResource.class)}; the
+ * {@link Rest#mixins() @Rest(mixins=WellKnownMixin.class)}; the
* {@code /.well-known/security.txt} URL becomes available alongside the host's own endpoints with
* no further wiring.
*
* <h5 class='section'>Hardcoded mount path:</h5>
*
* <p>
- * Unlike the sibling api-docs and ops mixins (see {@link BasicSwaggerResource},
- * {@link BasicVersionResource}, etc.), the mount path here is <b>not</b> SVL-configurable
+ * Unlike the sibling api-docs and ops mixins (see {@link SwaggerMixin},
+ * {@link VersionMixin}, etc.), the mount path here is <b>not</b> SVL-configurable
* — {@code /.well-known/security.txt} is fixed by
* <a href="https://www.rfc-editor.org/rfc/rfc8615">RFC 8615</a> (Well-Known URIs) and
* <a href="https://www.rfc-editor.org/rfc/rfc9116">RFC 9116</a> (security.txt). Both RFCs are
@@ -67,12 +67,12 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicWellKnownResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=WellKnownMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { }
*
* <jc>// Configure the security.txt body via a @Bean factory:</jc>
- * <ja>@Bean</ja> BasicWellKnownResource wellKnown() {
- * <jk>return</jk> BasicWellKnownResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> WellKnownMixin wellKnown() {
+ * <jk>return</jk> WellKnownMixin.<jsm>create</jsm>()
* .securityTxt(<js>"Contact: security@example.com\nExpires: 2027-01-01T00:00:00Z\n"</js>)
* .build();
* }
@@ -91,9 +91,9 @@ import org.apache.juneau.rest.annotation.*;
* </ul>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicFaviconResource}
- * <li class='jc'>{@link BasicSeoResource}
- * <li class='jc'>{@link BasicVersionResource}
+ * <li class='jc'>{@link FaviconMixin}
+ * <li class='jc'>{@link SeoMixin}
+ * <li class='jc'>{@link VersionMixin}
* <li class='link'><a class="doclink" href="https://www.rfc-editor.org/rfc/rfc8615">RFC 8615 — Well-Known URIs</a>
* <li class='link'><a class="doclink" href="https://www.rfc-editor.org/rfc/rfc9116">RFC 9116 — security.txt</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
@@ -103,7 +103,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicWellKnownResource {
+public class WellKnownMixin {
/**
* Creates a new builder.
@@ -117,7 +117,7 @@ public class BasicWellKnownResource {
private final String securityTxt;
/** No-arg constructor — results in a 404 on {@code /.well-known/security.txt}. */
- public BasicWellKnownResource() {
+ public WellKnownMixin() {
this(create());
}
@@ -126,7 +126,7 @@ public class BasicWellKnownResource {
*
* @param builder The builder.
*/
- protected BasicWellKnownResource(Builder builder) {
+ protected WellKnownMixin(Builder builder) {
securityTxt = builder.securityTxt;
}
@@ -162,13 +162,13 @@ public class BasicWellKnownResource {
}
/**
- * Builder for {@link BasicWellKnownResource} instances.
+ * Builder for {@link WellKnownMixin} instances.
*/
public static class Builder {
private String securityTxt;
- /** Constructor — package access for {@link BasicWellKnownResource#create()}. */
+ /** Constructor — package access for {@link WellKnownMixin#create()}. */
protected Builder() {}
/**
@@ -189,12 +189,12 @@ public class BasicWellKnownResource {
}
/**
- * Builds a {@link BasicWellKnownResource} instance.
+ * Builds a {@link WellKnownMixin} instance.
*
* @return A configured instance.
*/
- public BasicWellKnownResource build() {
- return new BasicWellKnownResource(this);
+ public WellKnownMixin build() {
+ return new WellKnownMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/package-info.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/package-info.java
index 81ccdac39a..5f8973ace6 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/package-info.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/convention/package-info.java
@@ -22,20 +22,20 @@
* <p>
* Four sibling mixins compose into the host {@code @Rest}-annotated resource. Each mixin owns its
* default mount paths and is independently mountable; the four together drop in as a pack via
- * {@code @Rest(mixins={BasicFaviconResource.class, BasicSeoResource.class, BasicVersionResource.class, BasicWellKnownResource.class})}.
+ * {@code @Rest(mixins={FaviconMixin.class, SeoMixin.class, VersionMixin.class, WellKnownMixin.class})}.
* </p>
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.convention.BasicFaviconResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.convention.FaviconMixin} —
* {@code /favicon.ico} with a 30-day {@code Cache-Control} and a default Juneau-branded icon
* on the framework classpath.
- * <li class='jc'>{@link org.apache.juneau.rest.convention.BasicSeoResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.convention.SeoMixin} —
* {@code /robots.txt} (deny-all by default) and {@code /sitemap.xml} (empty
* {@code <urlset>} by default); both builder-driven.
- * <li class='jc'>{@link org.apache.juneau.rest.convention.BasicVersionResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.convention.VersionMixin} —
* {@code /version}, {@code /info}, and {@code /about} returning the same JSON metadata
* map; defaults read {@code MANIFEST.MF} + {@code git.properties} from the classpath.
- * <li class='jc'>{@link org.apache.juneau.rest.convention.BasicWellKnownResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.convention.WellKnownMixin} —
* {@code /.well-known/security.txt} per RFC 9116; 404 unless explicitly configured.
* </ul>
*
@@ -45,18 +45,18 @@
* <ja>@Rest</ja>(
* path=<js>"/api"</js>,
* mixins={
- * BasicFaviconResource.<jk>class</jk>,
- * BasicSeoResource.<jk>class</jk>,
- * BasicVersionResource.<jk>class</jk>,
- * BasicWellKnownResource.<jk>class</jk>
+ * FaviconMixin.<jk>class</jk>,
+ * SeoMixin.<jk>class</jk>,
+ * VersionMixin.<jk>class</jk>,
+ * WellKnownMixin.<jk>class</jk>
* }
* )
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
- * <ja>@Bean</ja> BasicSeoResource seo() {
- * <jk>return</jk> BasicSeoResource.<jsm>create</jsm>().robotsAllow(<js>"*"</js>, <js>"/"</js>).build();
+ * <ja>@Bean</ja> SeoMixin seo() {
+ * <jk>return</jk> SeoMixin.<jsm>create</jsm>().robotsAllow(<js>"*"</js>, <js>"/"</js>).build();
* }
- * <ja>@Bean</ja> BasicWellKnownResource wellKnown() {
- * <jk>return</jk> BasicWellKnownResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> WellKnownMixin wellKnown() {
+ * <jk>return</jk> WellKnownMixin.<jsm>create</jsm>()
* .securityTxt(<js>"Contact: security@example.com\nExpires: 2027-01-01T00:00:00Z\n"</js>)
* .build();
* }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicOpenApiResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/OpenApiMixin.java
similarity index 94%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicOpenApiResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/OpenApiMixin.java
index 6d79f9a04a..91da7a30f8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicOpenApiResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/OpenApiMixin.java
@@ -46,8 +46,8 @@ import org.apache.juneau.yaml.*;
* </ul>
*
* <p>
- * Sibling of {@link BasicSwaggerResource} (Swagger v2 spec at {@code /api}),
- * {@link BasicSwaggerUiResource} (HTML-first mount at {@code /swagger}), and {@link BasicRedocResource}
+ * Sibling of {@link SwaggerMixin} (Swagger v2 spec at {@code /api}),
+ * {@link SwaggerUiMixin} (HTML-first mount at {@code /swagger}), and {@link RedocMixin}
* (HTML-first mount at {@code /redoc}). All four classes live in the
* {@code org.apache.juneau.rest.docs} api-docs mixin pack.
*
@@ -86,16 +86,16 @@ import org.apache.juneau.yaml.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=BasicOpenApiResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=OpenApiMixin.<jk>class</jk>)
* <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
* <jc>// Now also serves /myresource/openapi, /myresource/openapi.json, /myresource/openapi.yaml.</jc>
* }
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicSwaggerResource}
- * <li class='jc'>{@link BasicSwaggerUiResource}
- * <li class='jc'>{@link BasicRedocResource}
+ * <li class='jc'>{@link SwaggerMixin}
+ * <li class='jc'>{@link SwaggerUiMixin}
+ * <li class='jc'>{@link RedocMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -111,7 +111,7 @@ import org.apache.juneau.yaml.*;
ignoreTypes="OpenApi,org.apache.juneau.bean.html5.*",
useBeanDefs="true"
)
-public class BasicOpenApiResource {
+public class OpenApiMixin {
/**
* [GET /openapi] — emit the OpenAPI 3.1 document for this resource.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicRedocResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/RedocMixin.java
similarity index 86%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicRedocResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/RedocMixin.java
index 801dabbf91..33f913b8bf 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicRedocResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/RedocMixin.java
@@ -29,14 +29,14 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that publishes the Redoc HTML view at {@code /redoc} for the OpenAPI 3.1 spec.
*
* <p>
- * Sibling of {@link BasicSwaggerResource} (Swagger v2 spec at {@code /api}),
- * {@link BasicSwaggerUiResource} (HTML-first mount at {@code /swagger}), and {@link BasicOpenApiResource}
+ * Sibling of {@link SwaggerMixin} (Swagger v2 spec at {@code /api}),
+ * {@link SwaggerUiMixin} (HTML-first mount at {@code /swagger}), and {@link OpenApiMixin}
* (OpenAPI 3.1 spec at {@code /openapi*}). All four classes live in the
* {@code org.apache.juneau.rest.docs} api-docs mixin pack.
*
* <p>
- * Declares {@link Rest#mixins() @Rest(mixins={BasicOpenApiResource.class})} so transitive resolution
- * pulls in {@code BasicOpenApiResource} (and its {@code /openapi*} mounts) automatically when this
+ * Declares {@link Rest#mixins() @Rest(mixins={OpenApiMixin.class})} so transitive resolution
+ * pulls in {@code OpenApiMixin} (and its {@code /openapi*} mounts) automatically when this
* mixin is composed into a host.
*
* <h5 class='section'>Configurable mount path:</h5>
@@ -65,7 +65,7 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=BasicRedocResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=RedocMixin.<jk>class</jk>)
* <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
* <jc>// Serves /myresource/openapi, /openapi.json, /openapi.yaml (transitively) and /myresource/redoc (this mixin).</jc>
* }
@@ -80,9 +80,9 @@ import org.apache.juneau.rest.annotation.*;
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicSwaggerResource}
- * <li class='jc'>{@link BasicSwaggerUiResource}
- * <li class='jc'>{@link BasicOpenApiResource}
+ * <li class='jc'>{@link SwaggerMixin}
+ * <li class='jc'>{@link SwaggerUiMixin}
+ * <li class='jc'>{@link OpenApiMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -90,7 +90,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest(
- mixins={BasicOpenApiResource.class},
+ mixins={OpenApiMixin.class},
defaultAccept="text/html"
)
@JsonSchemaConfig(
@@ -99,7 +99,7 @@ import org.apache.juneau.rest.annotation.*;
ignoreTypes="OpenApi,org.apache.juneau.bean.html5.*",
useBeanDefs="true"
)
-public class BasicRedocResource {
+public class RedocMixin {
/**
* [GET /redoc] — render the Redoc HTML view (or the spec, depending on {@code Accept}).
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerMixin.java
similarity index 88%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerMixin.java
index 41e39f6812..d3f52fe373 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerMixin.java
@@ -29,13 +29,13 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that publishes the Swagger v2 spec endpoint at {@code /api/*}.
*
* <p>
- * Sibling of {@link BasicSwaggerUiResource} (HTML-first mount at {@code /swagger}),
- * {@link BasicOpenApiResource} (OpenAPI 3.1 spec at {@code /openapi*}), and
- * {@link BasicRedocResource} (HTML-first mount at {@code /redoc}). All four classes live in the
+ * Sibling of {@link SwaggerUiMixin} (HTML-first mount at {@code /swagger}),
+ * {@link OpenApiMixin} (OpenAPI 3.1 spec at {@code /openapi*}), and
+ * {@link RedocMixin} (HTML-first mount at {@code /redoc}). All four classes live in the
* {@code org.apache.juneau.rest.docs} api-docs mixin pack.
*
* <p>
- * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=BasicSwaggerResource.class)};
+ * Compose into a host resource via {@link Rest#mixins() @Rest(mixins=SwaggerMixin.class)};
* the {@code /api} URL becomes available alongside the host's own endpoints with no further wiring.
*
* <h5 class='section'>Configurable mount path:</h5>
@@ -64,7 +64,7 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=BasicSwaggerResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=SwaggerMixin.<jk>class</jk>)
* <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
* <ja>@RestGet</ja>(<js>"/items"</js>) <jk>public</jk> List<Item> items() { ... }
* <jc>// Now also serves /myresource/api with the Swagger v2 spec for this resource.</jc>
@@ -80,9 +80,9 @@ import org.apache.juneau.rest.annotation.*;
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicSwaggerUiResource}
- * <li class='jc'>{@link BasicOpenApiResource}
- * <li class='jc'>{@link BasicRedocResource}
+ * <li class='jc'>{@link SwaggerUiMixin}
+ * <li class='jc'>{@link OpenApiMixin}
+ * <li class='jc'>{@link RedocMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -96,7 +96,7 @@ import org.apache.juneau.rest.annotation.*;
ignoreTypes="Swagger,org.apache.juneau.bean.html5.*",
useBeanDefs="true"
)
-public class BasicSwaggerResource {
+public class SwaggerMixin {
/**
* [GET /api] — emit the Swagger v2 spec for this resource.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerUiMixin.java
similarity index 86%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerUiMixin.java
index e6e616d5ee..327231dbd5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/SwaggerUiMixin.java
@@ -29,14 +29,14 @@ import org.apache.juneau.rest.annotation.*;
* Mixin that publishes the Swagger-UI HTML view at {@code /swagger}.
*
* <p>
- * Sibling of {@link BasicSwaggerResource} (Swagger v2 spec at {@code /api}),
- * {@link BasicOpenApiResource} (OpenAPI 3.1 spec at {@code /openapi*}), and
- * {@link BasicRedocResource} (HTML-first mount at {@code /redoc}). All four classes live in the
+ * Sibling of {@link SwaggerMixin} (Swagger v2 spec at {@code /api}),
+ * {@link OpenApiMixin} (OpenAPI 3.1 spec at {@code /openapi*}), and
+ * {@link RedocMixin} (HTML-first mount at {@code /redoc}). All four classes live in the
* {@code org.apache.juneau.rest.docs} api-docs mixin pack.
*
* <p>
- * Declares {@link Rest#mixins() @Rest(mixins={BasicSwaggerResource.class})} so transitive resolution
- * pulls in {@code BasicSwaggerResource} (and its {@code /api} mount) automatically when this mixin
+ * Declares {@link Rest#mixins() @Rest(mixins={SwaggerMixin.class})} so transitive resolution
+ * pulls in {@code SwaggerMixin} (and its {@code /api} mount) automatically when this mixin
* is composed into a host. The two endpoints share the same Swagger document; they differ only in
* URL surface and content-negotiation defaults.
*
@@ -66,7 +66,7 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=BasicSwaggerUiResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/myresource"</js>, mixins=SwaggerUiMixin.<jk>class</jk>)
* <jk>public class</jk> MyResource <jk>extends</jk> RestServlet {
* <jc>// Serves /myresource/api (transitively) and /myresource/swagger (this mixin).</jc>
* }
@@ -86,9 +86,9 @@ import org.apache.juneau.rest.annotation.*;
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicSwaggerResource}
- * <li class='jc'>{@link BasicOpenApiResource}
- * <li class='jc'>{@link BasicRedocResource}
+ * <li class='jc'>{@link SwaggerMixin}
+ * <li class='jc'>{@link OpenApiMixin}
+ * <li class='jc'>{@link RedocMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -96,7 +96,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest(
- mixins={BasicSwaggerResource.class},
+ mixins={SwaggerMixin.class},
defaultAccept="text/html"
)
@JsonSchemaConfig(
@@ -105,7 +105,7 @@ import org.apache.juneau.rest.annotation.*;
ignoreTypes="Swagger,org.apache.juneau.bean.html5.*",
useBeanDefs="true"
)
-public class BasicSwaggerUiResource {
+public class SwaggerUiMixin {
/**
* [GET /swagger] — render the Swagger-UI HTML view (or the spec, depending on {@code Accept}).
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/package-info.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/package-info.java
index fd243a41b8..f30d93c6e4 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/package-info.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/docs/package-info.java
@@ -25,38 +25,38 @@
* </p>
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.docs.BasicSwaggerResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.docs.SwaggerMixin} —
* spec endpoint at {@code /api}, Swagger v2 + Swagger-UI swap.
- * <li class='jc'>{@link org.apache.juneau.rest.docs.BasicSwaggerUiResource} —
- * HTML-first mount at {@code /swagger}, transitively pulls in {@code BasicSwaggerResource}.
- * <li class='jc'>{@link org.apache.juneau.rest.docs.BasicOpenApiResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.docs.SwaggerUiMixin} —
+ * HTML-first mount at {@code /swagger}, transitively pulls in {@code SwaggerMixin}.
+ * <li class='jc'>{@link org.apache.juneau.rest.docs.OpenApiMixin} —
* spec endpoints at {@code /openapi}, {@code /openapi.json}, and {@code /openapi.yaml};
* OpenAPI 3.1 + Redoc swap on the content-negotiated {@code /openapi} mount.
- * <li class='jc'>{@link org.apache.juneau.rest.docs.BasicRedocResource} —
- * HTML-first mount at {@code /redoc}, transitively pulls in {@code BasicOpenApiResource}.
+ * <li class='jc'>{@link org.apache.juneau.rest.docs.RedocMixin} —
+ * HTML-first mount at {@code /redoc}, transitively pulls in {@code OpenApiMixin}.
* </ul>
*
* <h5 class='section'>Composition examples:</h5>
*
* <p class='bjava'>
* <jc>// OpenAPI 3.1 spec only — /openapi, /openapi.json, /openapi.yaml.</jc>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicOpenApiResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=OpenApiMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { ... }
*
* <jc>// OpenAPI 3.1 + Redoc — /openapi, /openapi.json, /openapi.yaml, /redoc.</jc>
- * <jc>// Transitive mixin resolution pulls BasicOpenApiResource in for free.</jc>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicRedocResource.<jk>class</jk>)
+ * <jc>// Transitive mixin resolution pulls OpenApiMixin in for free.</jc>
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=RedocMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { ... }
*
* <jc>// Everything — /api, /swagger, /openapi, /openapi.json, /openapi.yaml, /redoc.</jc>
- * <jc>// This is the post-9.5.0 default for BasicRestServlet / BasicRestObject subclasses.</jc>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins={BasicSwaggerUiResource.<jk>class</jk>, BasicRedocResource.<jk>class</jk>})
+ * <jc>// This is the post-9.5.0 default for BasicRestServlet / BasicRestResource subclasses.</jc>
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins={SwaggerUiMixin.<jk>class</jk>, RedocMixin.<jk>class</jk>})
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { ... }
* </p>
*
* <p>
- * The two UI mixins ({@link org.apache.juneau.rest.docs.BasicSwaggerUiResource} and
- * {@link org.apache.juneau.rest.docs.BasicRedocResource}) declare {@code @Rest(defaultAccept="text/html")}
+ * The two UI mixins ({@link org.apache.juneau.rest.docs.SwaggerUiMixin} and
+ * {@link org.apache.juneau.rest.docs.RedocMixin}) declare {@code @Rest(defaultAccept="text/html")}
* so that bare browser requests (no {@code Accept} header, or {@code Accept: *}{@code /*}) render the
* HTML view rather than the serializer-default media type. The two spec mixins use Juneau's standard
* content negotiation unchanged.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RateLimitGuard.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RateLimitGuard.java
index 896011fdc9..01cbbfe32b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RateLimitGuard.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/guard/RateLimitGuard.java
@@ -382,7 +382,7 @@ public class RateLimitGuard extends RestGuard {
* Point-in-time view of a single token bucket as exposed by {@link Storage#snapshot()}.
*
* <p>
- * Used by operator-facing tooling (e.g. {@code BasicAdminResource}'s {@code /admin/ratelimit} endpoint) to
+ * Used by operator-facing tooling (e.g. {@code AdminMixin}'s {@code /admin/ratelimit} endpoint) to
* surface live per-key bucket state alongside the static configuration. Token-bucket vocabulary
* intentionally — there is no discrete refill window because the bucket refills continuously at
* {@code permitsPerSecond}, so this record reports the current fill level ({@link #tokens()}), the integer
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/BasicHealthResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthAggregator.java
similarity index 66%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/BasicHealthResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthAggregator.java
index f95c1c3c45..fd7ba0db52 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/BasicHealthResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthAggregator.java
@@ -21,67 +21,53 @@ import static org.apache.juneau.commons.utils.StringUtils.*;
import java.time.*;
import java.util.*;
-import java.util.Map.*;
import java.util.concurrent.*;
import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.servlet.*;
/**
- * Built-in health/readiness/liveness probe resource.
+ * Shared health-probe aggregation worker bean.
+ *
+ * <p>
+ * Holds the capability logic for evaluating {@link HealthIndicator} beans and summarizing them into a
+ * probe response. The {@link HealthServlet} (servlet flavor) and {@link HealthMixin} (mixin flavor) are
+ * independent {@code @Rest} classes that each delegate to a {@code HealthAggregator}, so the two
+ * deployment forms cannot drift.
*
* @since 9.5.0
*/
-@Rest(paths={"/healthz","/readyz","/livez"})
-public class BasicHealthResource extends BasicRestServlet {
- private static final long serialVersionUID = 1L;
-
- /**
- * Health probe endpoint.
- *
- * @param res The response.
- * @return Aggregated health payload.
- */
- @RestGet(path="/healthz")
- public HealthResponse healthz(RestResponse res) {
- return aggregate(null, res);
- }
+public class HealthAggregator {
/**
- * Readiness probe endpoint.
+ * Resolves the {@link HealthIndicator} beans registered in the given context's bean store.
*
- * @param res The response.
- * @return Aggregated health payload.
+ * @param context The REST context whose bean store supplies the indicators.
+ * @return The indicator beans keyed by bean name.
*/
- @RestGet(path="/readyz")
- public HealthResponse readyz(RestResponse res) {
- return aggregate(HealthProbe.READY, res);
+ public Map<String,HealthIndicator> indicators(RestContext context) {
+ return context.getBeanStore().getBeansOfType(HealthIndicator.class);
}
/**
- * Liveness probe endpoint.
+ * Evaluates the supplied indicators, summarizes their statuses, and sets the response status.
*
- * @param res The response.
- * @return Aggregated health payload.
+ * @param context The REST context (supplies the {@link HealthProbeSettings} timeout).
+ * @param indicators The indicators to evaluate.
+ * @param probe The probe filter, or {@code null} to evaluate all indicators.
+ * @param res The response whose status code is set (200 healthy, 503 down).
+ * @return The aggregated health payload.
*/
- @RestGet(path="/livez")
- public HealthResponse livez(RestResponse res) {
- return aggregate(HealthProbe.LIVE, res);
- }
-
- private HealthResponse aggregate(HealthProbe probe, RestResponse res) {
+ public HealthResponse aggregate(RestContext context, Map<String,HealthIndicator> indicators, HealthProbe probe, RestResponse res) {
var out = new LinkedHashMap<String,ComponentHealth>();
- var timeout = getContext().getBeanStore().getBean(HealthProbeSettings.class).map(HealthProbeSettings::getTimeout).orElse(Duration.ofSeconds(1));
+ var timeout = context.getBeanStore().getBean(HealthProbeSettings.class).map(HealthProbeSettings::getTimeout).orElse(Duration.ofSeconds(1));
var timeoutMillis = Math.max(1L, timeout.toMillis());
- for (var e : indicators().entrySet()) {
+ for (var e : indicators.entrySet()) {
var indicator = e.getValue();
if (probe != null && !indicator.probes().contains(probe))
continue;
var componentName = firstNonEmpty(e.getKey(), indicator.getClass().getSimpleName());
- var component = runIndicator(componentName, indicator, timeoutMillis);
- out.put(componentName, component);
+ out.put(componentName, runIndicator(componentName, indicator, timeoutMillis));
}
var status = summarize(out.values());
@@ -89,15 +75,6 @@ public class BasicHealthResource extends BasicRestServlet {
return new HealthResponse(status, out);
}
- /**
- * Returns indicators to evaluate for this request.
- *
- * @return Indicator map keyed by bean name.
- */
- protected Map<String,HealthIndicator> indicators() {
- return getContext().getBeanStore().getBeansOfType(HealthIndicator.class);
- }
-
private static ComponentHealth runIndicator(String name, HealthIndicator indicator, long timeoutMillis) {
var future = CompletableFuture.supplyAsync(indicator::check);
try {
@@ -130,11 +107,20 @@ public class BasicHealthResource extends BasicRestServlet {
public static class HealthResponse {
private final HealthStatus status;
private final Map<String,ComponentHealth> components;
+
HealthResponse(HealthStatus status, Map<String,ComponentHealth> components) {
this.status = status;
this.components = components;
}
+
+ /**
+ * @return The aggregated probe status.
+ */
public HealthStatus getStatus() { return status; }
+
+ /**
+ * @return The per-component health entries.
+ */
public Map<String,ComponentHealth> getComponents() { return components; }
}
@@ -144,17 +130,27 @@ public class BasicHealthResource extends BasicRestServlet {
public static class ComponentHealth {
private final HealthStatus status;
private final Map<String,Object> details;
+
ComponentHealth(HealthStatus status, Map<String,Object> details) {
this.status = status;
this.details = details;
}
+
static ComponentHealth from(Health h) {
var details = new LinkedHashMap<>(h.getDetails());
if (h.getError() != null)
details.putIfAbsent("error", h.getError().toString());
return new ComponentHealth(h.getStatus(), details);
}
+
+ /**
+ * @return The component status.
+ */
public HealthStatus getStatus() { return status; }
+
+ /**
+ * @return The component detail map.
+ */
public Map<String,Object> getDetails() { return details; }
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthMixin.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthMixin.java
new file mode 100644
index 0000000000..9a45ace7f2
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthMixin.java
@@ -0,0 +1,85 @@
+/*
+ * 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.rest.health;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.health.HealthAggregator.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Mixin flavor of the built-in health/readiness/liveness probe capability.
+ *
+ * <p>
+ * Composes the {@code /healthz}, {@code /readyz}, and {@code /livez} probe endpoints into a host
+ * resource via {@link Rest#mixins() @Rest(mixins=HealthMixin.class)}. The ops self-pin their absolute
+ * paths so they merge into the host's namespace. Delegates to a shared {@link HealthAggregator} worker
+ * bean — the same logic the {@link HealthServlet} servlet flavor uses.
+ *
+ * <p>
+ * Indicators are resolved from the host's bean store, so a host registers its own
+ * {@link HealthIndicator} beans (e.g. via Spring {@code @Bean} or a Juneau {@code BeanStore}).
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link HealthServlet}
+ * <li class='jc'>{@link HealthAggregator}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+@Rest
+public class HealthMixin extends RestMixin {
+
+ private final HealthAggregator aggregator = new HealthAggregator();
+
+ /**
+ * Health probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/healthz")
+ public HealthResponse healthz(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), null, res);
+ }
+
+ /**
+ * Readiness probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/readyz")
+ public HealthResponse readyz(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.READY, res);
+ }
+
+ /**
+ * Liveness probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/livez")
+ public HealthResponse livez(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.LIVE, res);
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthResource.java
new file mode 100644
index 0000000000..27b5d8e8d4
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthResource.java
@@ -0,0 +1,87 @@
+/*
+ * 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.rest.health;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.health.HealthAggregator.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Child-resource flavor of the built-in health/readiness/liveness probe capability.
+ *
+ * <p>
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=HealthResource.class)}
+ * under a parent at the subtree {@code /health} and serves the {@code /healthz}, {@code /readyz}, and
+ * {@code /livez} probe endpoints by delegating to a shared {@link HealthAggregator} worker bean —
+ * the same logic the {@link HealthServlet servlet} and {@link HealthMixin mixin} flavors use, so the
+ * three forms cannot drift.
+ *
+ * <p>
+ * Indicators are resolved from the host's bean store, so a host registers its own
+ * {@link HealthIndicator} beans (e.g. via Spring {@code @Bean} or a Juneau {@code BeanStore}).
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link HealthServlet}
+ * <li class='jc'>{@link HealthMixin}
+ * <li class='jc'>{@link HealthAggregator}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+@Rest(path="/health")
+public class HealthResource extends RestResource {
+
+ private final transient HealthAggregator aggregator = new HealthAggregator();
+
+ /**
+ * Health probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/healthz")
+ public HealthResponse healthz(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), null, res);
+ }
+
+ /**
+ * Readiness probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/readyz")
+ public HealthResponse readyz(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.READY, res);
+ }
+
+ /**
+ * Liveness probe endpoint.
+ *
+ * @param req The request.
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/livez")
+ public HealthResponse livez(RestRequest req, RestResponse res) {
+ return aggregator.aggregate(req.getContext(), aggregator.indicators(req.getContext()), HealthProbe.LIVE, res);
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthServlet.java
new file mode 100644
index 0000000000..c40114c460
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/health/HealthServlet.java
@@ -0,0 +1,93 @@
+/*
+ * 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.rest.health;
+
+import java.util.*;
+
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.health.HealthAggregator.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Servlet flavor of the built-in health/readiness/liveness probe capability.
+ *
+ * <p>
+ * Mounts as a standalone top-level servlet at {@code /healthz}, {@code /readyz}, and {@code /livez},
+ * delegating to a shared {@link HealthAggregator} worker bean. The {@link HealthMixin} mixin flavor
+ * delegates to the same bean, so the two forms cannot drift.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link HealthMixin}
+ * <li class='jc'>{@link HealthAggregator}
+ * </ul>
+ *
+ * @serial exclude
+ * @since 9.5.0
+ */
+@Rest(paths={"/healthz","/readyz","/livez"})
+public class HealthServlet extends BasicRestServlet {
+ private static final long serialVersionUID = 1L;
+
+ private final transient HealthAggregator aggregator = new HealthAggregator();
+
+ /**
+ * Health probe endpoint.
+ *
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/healthz")
+ public HealthResponse healthz(RestResponse res) {
+ return aggregator.aggregate(getContext(), indicators(), null, res);
+ }
+
+ /**
+ * Readiness probe endpoint.
+ *
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/readyz")
+ public HealthResponse readyz(RestResponse res) {
+ return aggregator.aggregate(getContext(), indicators(), HealthProbe.READY, res);
+ }
+
+ /**
+ * Liveness probe endpoint.
+ *
+ * @param res The response.
+ * @return Aggregated health payload.
+ */
+ @RestGet(path="/livez")
+ public HealthResponse livez(RestResponse res) {
+ return aggregator.aggregate(getContext(), indicators(), HealthProbe.LIVE, res);
+ }
+
+ /**
+ * Returns the indicators to evaluate for this request.
+ *
+ * <p>
+ * Defaults to every {@link HealthIndicator} bean registered in this resource's bean store.
+ * Subclasses may override to supply a fixed indicator set.
+ *
+ * @return Indicator map keyed by bean name.
+ */
+ protected Map<String,HealthIndicator> indicators() {
+ return aggregator.indicators(getContext());
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminMixin.java
similarity index 95%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminMixin.java
index 39bb9743d8..562fac3866 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminMixin.java
@@ -35,8 +35,8 @@ import org.apache.juneau.rest.guard.RateLimitGuard.BucketState;
* heap statistics, configurable cache-flush hooks, and rate-limit-bucket inspection.
*
* <p>
- * Sibling of {@link BasicEchoResource} ({@code /echo/*} / {@code /debug/echo/*}) and
- * {@link BasicRouteIndexResource} ({@code /options} / {@code /routes}). All three classes live in
+ * Sibling of {@link EchoMixin} ({@code /echo/*} / {@code /debug/echo/*}) and
+ * {@link RouteIndexMixin} ({@code /options} / {@code /routes}). All three classes live in
* the {@code org.apache.juneau.rest.ops} ops/introspection mixin pack.
*
* <h5 class='section'>Default-deny security posture:</h5>
@@ -86,7 +86,7 @@ import org.apache.juneau.rest.guard.RateLimitGuard.BucketState;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicAdminResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=AdminMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
*
* <jc>// Required: register an auth guard chain to unlock the admin paths.</jc>
@@ -97,8 +97,8 @@ import org.apache.juneau.rest.guard.RateLimitGuard.BucketState;
* .build();
* }
*
- * <ja>@Bean</ja> BasicAdminResource admin() {
- * <jk>return</jk> BasicAdminResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> AdminMixin admin() {
+ * <jk>return</jk> AdminMixin.<jsm>create</jsm>()
* .cacheFlush(<js>"primary"</js>, () -> primaryCache.invalidateAll())
* .build();
* }
@@ -136,8 +136,8 @@ import org.apache.juneau.rest.guard.RateLimitGuard.BucketState;
* stays out of any generated Swagger / OpenAPI spec.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicEchoResource}
- * <li class='jc'>{@link BasicRouteIndexResource}
+ * <li class='jc'>{@link EchoMixin}
+ * <li class='jc'>{@link RouteIndexMixin}
* <li class='jc'>{@link DenyAllGuard}
* <li class='jc'>{@link RestGuardList}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
@@ -149,7 +149,7 @@ import org.apache.juneau.rest.guard.RateLimitGuard.BucketState;
@Rest(
guards=DenyAllGuard.class
)
-public class BasicAdminResource {
+public class AdminMixin {
/**
* Default thread-name-prefix exclude list: filter out JVM internals, servlet container, and
@@ -175,7 +175,7 @@ public class BasicAdminResource {
private final List<String> threadNamePrefixExclude;
/** No-arg constructor — uses the default thread filter and no cache-flush hooks. */
- public BasicAdminResource() {
+ public AdminMixin() {
this(create());
}
@@ -184,7 +184,7 @@ public class BasicAdminResource {
*
* @param builder The builder.
*/
- protected BasicAdminResource(Builder builder) {
+ protected AdminMixin(Builder builder) {
cacheFlushHooks = Collections.unmodifiableMap(new LinkedHashMap<>(builder.cacheFlushHooks));
threadNamePrefixExclude = List.copyOf(builder.threadNamePrefixExclude);
}
@@ -391,14 +391,14 @@ public class BasicAdminResource {
}
/**
- * Builder for {@link BasicAdminResource} instances.
+ * Builder for {@link AdminMixin} instances.
*/
public static class Builder {
private final Map<String,Runnable> cacheFlushHooks = new LinkedHashMap<>();
private final List<String> threadNamePrefixExclude = new ArrayList<>(DEFAULT_THREAD_NAME_PREFIX_EXCLUDE);
- /** Constructor — package access for {@link BasicAdminResource#create()}. */
+ /** Constructor — package access for {@link AdminMixin#create()}. */
protected Builder() {}
/**
@@ -454,12 +454,12 @@ public class BasicAdminResource {
}
/**
- * Builds a {@link BasicAdminResource} instance.
+ * Builds a {@link AdminMixin} instance.
*
* @return A configured instance.
*/
- public BasicAdminResource build() {
- return new BasicAdminResource(this);
+ public AdminMixin build() {
+ return new AdminMixin(this);
}
/**
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminResource.java
similarity index 67%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminResource.java
index 1ee5c9a64b..b7a8198b4b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminResource.java
@@ -26,69 +26,57 @@ import org.apache.juneau.rest.guard.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicAdminResource} mixin.
+ * Child-resource flavor of the {@link AdminMixin} mixin.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /admin/*} and serves the same operational
- * endpoints ({@code /threads}, {@code /heap}, {@code /cache/flush}, {@code /ratelimit}) as the
- * mixin by delegating to a shared {@link BasicAdminResource} instance — so the two forms
- * cannot drift.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=AdminResource.class)} under
+ * a parent at the subtree {@code /admin} and serves the same operational endpoints ({@code /threads},
+ * {@code /heap}, {@code /cache/flush}, {@code /ratelimit}) as the mixin by delegating to a shared
+ * {@link AdminMixin} instance — so the forms cannot drift.
*
* <p>
- * Whereas the {@link BasicAdminResource} mixin pins its ops at {@code /admin/<endpoint>} for
- * composition into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/admin/*")}) and pins the ops at the bare endpoint names
- * (e.g. {@code /threads}) — eliminating the path-doubling that mixin-shaped ops would produce
- * when the servlet itself is mounted at {@code /admin/*}.
+ * Whereas the {@link AdminMixin} mixin pins its ops at {@code /admin/<endpoint>} for composition into a
+ * host at {@code /}, this child declares the subtree at the class level
+ * ({@link Rest#path() @Rest(path="/admin")}) and pins the ops at the bare endpoint names
+ * (e.g. {@code /threads}).
*
* <h5 class='section'>Default-deny security posture:</h5>
*
* <p>
- * Like the mixin, this servlet is annotated {@link Rest#guards() @Rest(guards=DenyAllGuard.class)},
- * so every admin path returns {@code 403 Forbidden} until the importer registers a
- * {@link RestGuardList} factory. Pair the servlet with whatever authentication / authorization
- * story your service uses.
- *
- * <h5 class='figure'>Microservice registration:</h5>
- *
- * <p class='bjava'>
- * <ja>@Bean</ja> Servlet admin() {
- * <jk>return new</jk> BasicAdminServlet(); <jc>// auto-mounted at /admin/* by JettyServerComponent</jc>
- * }
- * </p>
+ * Like the mixin and servlet flavors, this child is annotated
+ * {@link Rest#guards() @Rest(guards=DenyAllGuard.class)}, so every admin path returns
+ * {@code 403 Forbidden} until the importer registers a {@link RestGuardList} factory.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicAdminResource}
+ * <li class='jc'>{@link AdminMixin}
+ * <li class='jc'>{@link AdminServlet}
* <li class='jc'>{@link DenyAllGuard}
* <li class='jc'>{@link RestGuardList}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
// @formatter:off
@Rest(
- paths="/admin/*",
+ path="/admin",
guards=DenyAllGuard.class
)
-public class BasicAdminServlet extends RestServlet {
-
- private static final long serialVersionUID = 1L;
+public class AdminResource extends RestResource {
- private final transient BasicAdminResource delegate;
+ private final transient AdminMixin delegate;
- /** No-arg constructor — uses a default {@link BasicAdminResource} delegate. */
- public BasicAdminServlet() {
- this(new BasicAdminResource());
+ /** No-arg constructor — uses a default {@link AdminMixin} delegate. */
+ public AdminResource() {
+ this(new AdminMixin());
}
/**
* Delegate constructor.
*
- * @param delegate The shared admin mixin this servlet delegates to. Must not be {@code null}.
+ * @param delegate The shared admin mixin this child delegates to. Must not be {@code null}.
*/
- protected BasicAdminServlet(BasicAdminResource delegate) {
+ protected AdminResource(AdminMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminServlet.java
similarity index 87%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminServlet.java
index 1ee5c9a64b..dd46807e7f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicAdminServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/AdminServlet.java
@@ -26,16 +26,16 @@ import org.apache.juneau.rest.guard.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicAdminResource} mixin.
+ * Standalone servlet companion of the {@link AdminMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /admin/*} and serves the same operational
* endpoints ({@code /threads}, {@code /heap}, {@code /cache/flush}, {@code /ratelimit}) as the
- * mixin by delegating to a shared {@link BasicAdminResource} instance — so the two forms
+ * mixin by delegating to a shared {@link AdminMixin} instance — so the two forms
* cannot drift.
*
* <p>
- * Whereas the {@link BasicAdminResource} mixin pins its ops at {@code /admin/<endpoint>} for
+ * Whereas the {@link AdminMixin} mixin pins its ops at {@code /admin/<endpoint>} for
* composition into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/admin/*")}) and pins the ops at the bare endpoint names
* (e.g. {@code /threads}) — eliminating the path-doubling that mixin-shaped ops would produce
@@ -53,12 +53,12 @@ import org.apache.juneau.rest.servlet.*;
*
* <p class='bjava'>
* <ja>@Bean</ja> Servlet admin() {
- * <jk>return new</jk> BasicAdminServlet(); <jc>// auto-mounted at /admin/* by JettyServerComponent</jc>
+ * <jk>return new</jk> AdminServlet(); <jc>// auto-mounted at /admin/* by JettyServerComponent</jc>
* }
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicAdminResource}
+ * <li class='jc'>{@link AdminMixin}
* <li class='jc'>{@link DenyAllGuard}
* <li class='jc'>{@link RestGuardList}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
@@ -72,15 +72,15 @@ import org.apache.juneau.rest.servlet.*;
paths="/admin/*",
guards=DenyAllGuard.class
)
-public class BasicAdminServlet extends RestServlet {
+public class AdminServlet extends RestServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicAdminResource delegate;
+ private final transient AdminMixin delegate;
- /** No-arg constructor — uses a default {@link BasicAdminResource} delegate. */
- public BasicAdminServlet() {
- this(new BasicAdminResource());
+ /** No-arg constructor — uses a default {@link AdminMixin} delegate. */
+ public AdminServlet() {
+ this(new AdminMixin());
}
/**
@@ -88,7 +88,7 @@ public class BasicAdminServlet extends RestServlet {
*
* @param delegate The shared admin mixin this servlet delegates to. Must not be {@code null}.
*/
- protected BasicAdminServlet(BasicAdminResource delegate) {
+ protected AdminServlet(AdminMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicEchoResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/EchoMixin.java
similarity index 94%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicEchoResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/EchoMixin.java
index 0c3cb1eeb4..ef09659c41 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicEchoResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/EchoMixin.java
@@ -31,13 +31,13 @@ import org.apache.juneau.rest.annotation.*;
* (configurable).
*
* <p>
- * Sibling of {@link BasicAdminResource} ({@code /admin/*}) and {@link BasicRouteIndexResource}
+ * Sibling of {@link AdminMixin} ({@code /admin/*}) and {@link RouteIndexMixin}
* ({@code /options}, {@code /routes}). All three classes live in the
* {@code org.apache.juneau.rest.ops} ops/introspection mixin pack.
*
* <p>
* Compose into a host resource via
- * {@link Rest#mixins() @Rest(mixins=BasicEchoResource.class)}; the {@code /echo/*} URL becomes
+ * {@link Rest#mixins() @Rest(mixins=EchoMixin.class)}; the {@code /echo/*} URL becomes
* available alongside the host's own endpoints with no further wiring.
*
* <h5 class='section'>Configurable mount path:</h5>
@@ -76,14 +76,14 @@ import org.apache.juneau.rest.annotation.*;
* <p class='bjava'>
* <ja>@Rest</ja>(
* path=<js>"/api"</js>,
- * mixins=BasicEchoResource.<jk>class</jk>,
+ * mixins=EchoMixin.<jk>class</jk>,
* debug=<js>"conditional"</js> <jc>// gates the echo endpoint per request</jc>
* )
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet { }
*
* <jc>// Optional: tighten the body cap or adjust redacted headers via a @Bean factory:</jc>
- * <ja>@Bean</ja> BasicEchoResource echo() {
- * <jk>return</jk> BasicEchoResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> EchoMixin echo() {
+ * <jk>return</jk> EchoMixin.<jsm>create</jsm>()
* .bodyLimit(64 * 1024L)
* .redactHeader(<js>"X-Internal-Trace"</js>)
* .build();
@@ -144,8 +144,8 @@ import org.apache.juneau.rest.annotation.*;
* {@link OpSwagger#ignore() @OpSwagger(ignore=true)}.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicAdminResource}
- * <li class='jc'>{@link BasicRouteIndexResource}
+ * <li class='jc'>{@link AdminMixin}
+ * <li class='jc'>{@link RouteIndexMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -153,7 +153,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicEchoResource {
+public class EchoMixin {
/** Sentinel value emitted in place of redacted header values. */
public static final String REDACTED = "[REDACTED]";
@@ -181,7 +181,7 @@ public class BasicEchoResource {
private final Set<String> redactedHeadersLower;
/** No-arg constructor — uses {@link #DEFAULT_BODY_LIMIT} and {@link #DEFAULT_REDACTED_HEADERS}. */
- public BasicEchoResource() {
+ public EchoMixin() {
this(create());
}
@@ -190,7 +190,7 @@ public class BasicEchoResource {
*
* @param builder The builder.
*/
- protected BasicEchoResource(Builder builder) {
+ protected EchoMixin(Builder builder) {
bodyLimit = builder.bodyLimit;
var s = new LinkedHashSet<String>();
for (var h : builder.redactedHeaders)
@@ -316,14 +316,14 @@ public class BasicEchoResource {
}
/**
- * Builder for {@link BasicEchoResource} instances.
+ * Builder for {@link EchoMixin} instances.
*/
public static class Builder {
private long bodyLimit = DEFAULT_BODY_LIMIT;
private final Set<String> redactedHeaders;
- /** Constructor — package access for {@link BasicEchoResource#create()}. */
+ /** Constructor — package access for {@link EchoMixin#create()}. */
protected Builder() {
redactedHeaders = new LinkedHashSet<>(DEFAULT_REDACTED_HEADERS);
}
@@ -379,12 +379,12 @@ public class BasicEchoResource {
}
/**
- * Builds a {@link BasicEchoResource} instance.
+ * Builds a {@link EchoMixin} instance.
*
* @return A configured instance.
*/
- public BasicEchoResource build() {
- return new BasicEchoResource(this);
+ public EchoMixin build() {
+ return new EchoMixin(this);
}
}
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/ErrorMixin.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/ErrorMixin.java
new file mode 100644
index 0000000000..eb659e126a
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/ErrorMixin.java
@@ -0,0 +1,56 @@
+/*
+ * 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.rest.ops;
+
+import static org.apache.juneau.http.HttpMethod.*;
+
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Mixin providing the residual {@code [* /error]} endpoint.
+ *
+ * <p>
+ * Single-responsibility op-mixin carved out of the former {@code BasicRestOperations} interface. Compose
+ * into a host via {@link Rest#mixins() @Rest(mixins=ErrorMixin.class)}; the {@link BasicRestServlet} family
+ * pulls it in by default.
+ *
+ * <p>
+ * Servlet chains often redirect to {@code /error} when an error condition occurs (such as failed
+ * authentication) and set appropriate response parameters (such as a {@code WWW-Authenticate} header).
+ *
+ * @since 9.5.0
+ */
+@Rest
+public class ErrorMixin extends RestMixin {
+
+ /**
+ * [* /error] - Error occurred.
+ */
+ @RestOp(
+ method=ANY,
+ path="/error",
+ summary="Error occurred",
+ description={
+ "An error occurred during handling of the request. ",
+ "Servlet chains will often automatically redirect to '/error' when any sort of error condition occurs ",
+ "(such as failed authentication) and will set appropriate response parameters ",
+ "(such as an WWW-Authenticate response header)."
+ }
+ )
+ public void error() {}
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/HtdocMixin.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/HtdocMixin.java
new file mode 100644
index 0000000000..538760ce8e
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/HtdocMixin.java
@@ -0,0 +1,67 @@
+/*
+ * 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.rest.ops;
+
+import java.util.*;
+
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.response.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Mixin providing the residual {@code [GET /htdocs/*]} static-file endpoint.
+ *
+ * <p>
+ * Single-responsibility op-mixin carved out of the former {@code BasicRestOperations} interface. Resolves
+ * the requested path against the active {@link org.apache.juneau.rest.staticfile.StaticFiles} bean via
+ * {@link RestContext#getStaticFiles()}.
+ *
+ * <p>
+ * The greedy {@code /htdocs/*} blob handler is not API-meaningful and is excluded from the published
+ * Swagger/OpenAPI specification via {@link OpSwagger#ignore() @OpSwagger(ignore=true)}.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link org.apache.juneau.rest.staticfile.StaticFilesMixin}
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+@Rest
+public class HtdocMixin extends RestMixin {
+
+ /**
+ * [GET /htdocs/*] - Retrieve static file.
+ *
+ * @param req The HTTP request.
+ * @param path The path to retrieve.
+ * @param locale The locale of the HTTP request.
+ * @return An HTTP resource representing the static file.
+ * @throws NotFound If no resource matches the requested path.
+ */
+ @RestGet(
+ path="/htdocs/*",
+ summary="Static files",
+ description="Static file retrieval.",
+ swagger=@OpSwagger(ignore=true)
+ )
+ public HttpResource getHtdoc(RestRequest req, @Path("/*") String path, Locale locale) throws NotFound {
+ return req.getContext().getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicRouteIndexResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/RouteIndexMixin.java
similarity index 95%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicRouteIndexResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/RouteIndexMixin.java
index a94828a6d7..136daf8f4c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/BasicRouteIndexResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/RouteIndexMixin.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.annotation.*;
* resource (and any other mixins on it) at {@code /options} (configurable).
*
* <p>
- * Sibling of {@link BasicEchoResource} ({@code /echo/*}) and {@link BasicAdminResource}
+ * Sibling of {@link EchoMixin} ({@code /echo/*}) and {@link AdminMixin}
* ({@code /admin/*}). All three classes live in the {@code org.apache.juneau.rest.ops}
* ops/introspection mixin pack.
*
@@ -70,7 +70,7 @@ import org.apache.juneau.rest.annotation.*;
* <h5 class='figure'>Composition example:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicRouteIndexResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=RouteIndexMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
* <ja>@RestGet</ja>(path=<js>"/items"</js>, summary=<js>"List items"</js>) <jk>public</jk> List<Item> items() { ... }
* }
@@ -115,8 +115,8 @@ import org.apache.juneau.rest.annotation.*;
* route-index endpoint is excluded from the OpenAPI spec.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicEchoResource}
- * <li class='jc'>{@link BasicAdminResource}
+ * <li class='jc'>{@link EchoMixin}
+ * <li class='jc'>{@link AdminMixin}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
@@ -124,14 +124,14 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicRouteIndexResource {
+public class RouteIndexMixin {
private static final List<Class<? extends Annotation>> REST_OP_ANNOTATIONS = List.of(
RestGet.class, RestPost.class, RestPut.class, RestDelete.class,
RestPatch.class, RestOptions.class, RestOp.class);
/** No-arg constructor — route-index has no configurable state. */
- public BasicRouteIndexResource() {}
+ public RouteIndexMixin() {}
/**
* [GET /options] — emit the route index as a JSON list.
@@ -176,7 +176,7 @@ public class BasicRouteIndexResource {
for (var mixinCtx : hostCtx.getMixinContexts().values())
for (var oc : mixinCtx.getRestOperations().getOpContexts())
addEntry(entries, seen, oc);
- entries.sort(BasicRouteIndexResource::compareByPathThenMethod);
+ entries.sort(RouteIndexMixin::compareByPathThenMethod);
return entries;
}
@@ -218,7 +218,7 @@ public class BasicRouteIndexResource {
}
private static boolean isSelfHandler(Method m) {
- return m.getDeclaringClass() == BasicRouteIndexResource.class;
+ return m.getDeclaringClass() == RouteIndexMixin.class;
}
@SuppressWarnings("java:S3776") // Same as isHiddenFromIndex — short loop, single concern.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/StatsMixin.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/StatsMixin.java
new file mode 100644
index 0000000000..344cadc72a
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/StatsMixin.java
@@ -0,0 +1,64 @@
+/*
+ * 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.rest.ops;
+
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+import org.apache.juneau.rest.stats.*;
+
+/**
+ * Mixin providing the residual {@code [GET /stats]} timing-statistics endpoint.
+ *
+ * <p>
+ * Single-responsibility op-mixin carved out of the former {@code BasicRestOperations} interface. Carries
+ * the per-method {@link HtmlDocConfig @HtmlDocConfig} that customizes the {@code /stats} HTML page (per
+ * OQ-8 — the per-method config travels with the op, while the host-wide navlinks/JSON-schema config
+ * lives at the class level on {@link BasicRestServlet}).
+ *
+ * @since 9.5.0
+ */
+@Rest
+public class StatsMixin extends RestMixin {
+
+ /**
+ * [GET /stats] - Timing statistics.
+ *
+ * <p>
+ * Timing statistics for method invocations on this resource.
+ *
+ * @param req The HTTP request.
+ * @return A collection of timing statistics for each annotated method on this resource.
+ */
+ @RestGet(
+ path="/stats",
+ summary="Timing statistics",
+ description="Timing statistics for method invocations on this resource."
+ )
+ @HtmlDocConfig(
+ // Should override config annotations defined on class.
+ rank=10,
+ // Override the nav links for the swagger page.
+ navlinks = { "back: servlet:/", "json: servlet:/stats?Accept=text/json&plainText=true" },
+ // Never show aside contents of page inherited from class.
+ aside="NONE"
+ )
+ public RestContextStats getStats(RestRequest req) {
+ return req.getContext().getStats();
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/package-info.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/package-info.java
index f28f2a722b..1438c3dfa9 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/package-info.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/ops/package-info.java
@@ -23,20 +23,20 @@
* Three sibling mixins compose into the host {@code @Rest}-annotated resource. Each mixin owns
* its default mount paths, ships secure-by-default (debug-gated for echo, deny-all-guard for
* admin), and is independently mountable; the three together drop in as a pack via
- * {@code @Rest(mixins={BasicEchoResource.class, BasicAdminResource.class, BasicRouteIndexResource.class})}.
+ * {@code @Rest(mixins={EchoMixin.class, AdminMixin.class, RouteIndexMixin.class})}.
* </p>
*
* <ul class='javatreec'>
- * <li class='jc'>{@link org.apache.juneau.rest.ops.BasicEchoResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.ops.EchoMixin} —
* {@code /echo/*} and {@code /debug/echo/*} request echo, gated behind the host's
* {@link org.apache.juneau.rest.debug.DebugEnablement DebugEnablement}; sensitive headers
* ({@code Authorization}, {@code Cookie}, etc.) are redacted by default.
- * <li class='jc'>{@link org.apache.juneau.rest.ops.BasicAdminResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.ops.AdminMixin} —
* {@code /admin/threads}, {@code /admin/heap}, {@code /admin/cache/flush} (POST), and
* {@code /admin/ratelimit}; default-deny via
* {@link org.apache.juneau.rest.guard.DenyAllGuard} until the importer registers an
* {@code @Bean RestGuardList} factory.
- * <li class='jc'>{@link org.apache.juneau.rest.ops.BasicRouteIndexResource} —
+ * <li class='jc'>{@link org.apache.juneau.rest.ops.RouteIndexMixin} —
* {@code /options} and {@code /routes} returning a JSON list of every
* {@code @RestOp}-annotated method on the host (plus mixins), excluding
* {@code @OpSwagger(ignore=true)} ops.
@@ -48,11 +48,11 @@
* <ja>@Rest</ja>(
* path=<js>"/api"</js>,
* mixins={
- * BasicEchoResource.<jk>class</jk>,
- * BasicAdminResource.<jk>class</jk>,
- * BasicRouteIndexResource.<jk>class</jk>
+ * EchoMixin.<jk>class</jk>,
+ * AdminMixin.<jk>class</jk>,
+ * RouteIndexMixin.<jk>class</jk>
* },
- * debug=<js>"conditional"</js> <jc>// gates BasicEchoResource per-request</jc>
+ * debug=<js>"conditional"</js> <jc>// gates EchoMixin per-request</jc>
* )
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
*
@@ -64,8 +64,8 @@
* .build();
* }
*
- * <ja>@Bean</ja> BasicAdminResource admin() {
- * <jk>return</jk> BasicAdminResource.<jsm>create</jsm>()
+ * <ja>@Bean</ja> AdminMixin admin() {
+ * <jk>return</jk> AdminMixin.<jsm>create</jsm>()
* .cacheFlush(<js>"primary"</js>, () -> primaryCache.invalidateAll())
* .build();
* }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicGroupOperations.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicGroupOperations.java
deleted file mode 100644
index 488cc769d4..0000000000
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicGroupOperations.java
+++ /dev/null
@@ -1,66 +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.rest.servlet;
-
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.beans.*;
-
-/**
- * Basic REST group operation methods.
- *
- * <p>
- * Defines the residual {@code GET /} navigation endpoint for group resources. The legacy
- * {@code ?Swagger} / {@code ?OpenApi} query-mirror overloads were removed in 9.5.0; clients should
- * now hit {@code /api}, {@code /swagger}, {@code /openapi}, or {@code /redoc} directly (always
- * mounted via the api-docs mixin pack on {@code BasicRestServlet} / {@code BasicRestObject}).
- * </p>
- *
- * <p class='bjava'>
- * <ja>@RestGet</ja>(path=<js>"/"</js>)
- * <jk>public</jk> {@link ChildResourceDescriptions} {@link #getChildren(RestRequest) getChildren}({@link RestRequest} <jv>req</jv>);
- * </p>
- *
- * <p>
- * Implementations provided by the following classes:
- * </p>
- * <ul class='javatreec'>
- * <li class='jac'>{@link BasicRestServletGroup}
- * <li class='jac'>{@link BasicRestObjectGroup}
- * </ul>
- *
- * <h5 class='section'>See Also:</h5><ul>
- * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestAnnotatedClassBasics">@Rest-Annotated Class Basics</a>
- * </ul>
- */
-public interface BasicGroupOperations {
-
- /**
- * [GET /] - Get child resources.
- *
- * <p>
- * Returns a bean that lists and allows navigation to child resources. Default implementation
- * delegates to {@link ChildResourceDescriptions#of(RestRequest)}; subclasses may override.
- *
- * @param req The HTTP request.
- * @return The bean containing links to the child resources.
- */
- @RestGet(path = "/", summary = "Navigation page")
- default ChildResourceDescriptions getChildren(RestRequest req) {
- return ChildResourceDescriptions.of(req);
- }
-}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestOperations.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestOperations.java
deleted file mode 100644
index cc5d20e405..0000000000
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestOperations.java
+++ /dev/null
@@ -1,162 +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.rest.servlet;
-
-import static org.apache.juneau.http.HttpMethod.*;
-
-import java.util.*;
-
-import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.jsonschema.annotation.*;
-import org.apache.juneau.rest.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.docs.*;
-import org.apache.juneau.rest.stats.*;
-
-/**
- * Basic REST operation methods.
- *
- * <p>
- * Defines the residual cross-cutting endpoints that are still part of the {@code BasicRestServlet}
- * chain after the API-docs surface ({@code /api}, {@code /openapi}, etc.) was lifted into the
- * {@link BasicSwaggerResource} / {@link BasicSwaggerUiResource} / {@link BasicOpenApiResource} /
- * {@link BasicRedocResource} mixin pack:
- * </p>
- *
- * <p class='bjava'>
- * <ja>@RestGet</ja>(path=<js>"/htdocs/*"</js>)
- * <jk>public</jk> {@link HttpResource} {@link #getHtdoc(String,Locale) getHtdoc}(<ja>@Path</ja> String <jv>path</jv>, Locale <jv>locale</jv>);
- *
- * <ja>@RestGet</ja>(path=<js>"favicon.ico"</js>)
- * <jk>public</jk> {@link HttpResource} {@link #getFavIcon() getFavIcon}();
- *
- * <ja>@RestGet</ja>(path=<js>"/stats"</js>)
- * <jk>public</jk> {@link RestContextStats} {@link #getStats(RestRequest) getStats}({@link RestRequest} <jv>req</jv>);
- *
- * <ja>@RestOp</ja>(method=<jsf>ANY</jsf>, path=<js>"/error"</js>)
- * <jk>public void</jk> {@link #error() error}();
- * </p>
- *
- * <p>
- * Implementations provided by the following classes:
- * </p>
- * <ul class='javatreec'>
- * <li class='jac'>{@link BasicRestServlet}
- * <li class='jac'>{@link BasicRestServletGroup}
- * <li class='jac'>{@link BasicRestObject}
- * <li class='jac'>{@link BasicRestObjectGroup}
- * </ul>
- *
- * <h5 class='section'>See Also:</h5><ul>
- * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestAnnotatedClassBasics">@Rest-Annotated Class Basics</a>
- * </ul>
- */
-// @formatter:off
-@HtmlDocConfig(
- // Basic page navigation links.
- navlinks={
- "up: request:/..",
- "api: servlet:/api",
- "stats: servlet:/stats"
- }
-)
-@JsonSchemaConfig(
- // Add descriptions to the following types when not specified:
- addDescriptionsTo="bean,collection,array,map,enum",
- // Add example to the following types:
- addExamplesTo="bean,collection,array,map",
- // Don't generate schema information on the Swagger / OpenApi beans themselves or HTML beans.
- ignoreTypes="Swagger,OpenApi,org.apache.juneau.bean.html5.*",
- // Use $ref references for bean definitions to reduce duplication in generated specs.
- useBeanDefs="true"
-)
-public interface BasicRestOperations {
-
- /**
- * [* /error] - Error occurred.
- */
- @RestOp(
- method=ANY,
- path="/error",
- summary="Error occurred",
- description={
- "An error occurred during handling of the request. ",
- "Servlet chains will often automatically redirect to '/error' when any sort of error condition occurs ",
- "(such as failed authentication) and will set appropriate response parameters ",
- "(such as an WWW-Authenticate response header)."
- }
- ) void error();
-
- /**
- * [GET favicon.ico] - Retrieve favorites icon image.
- *
- * @return A bean containing the contents for the OPTIONS page.
- */
- @RestGet(
- path="favicon.ico",
- summary="Favorites icon.",
- description="Favorites icon."
- ) HttpResource getFavIcon();
-
- /**
- * [GET /htdocs/*] - Retrieve static file.
- *
- * <p>
- * Excluded from the published Swagger/OpenAPI specification via
- * {@link OpSwagger#ignore() @OpSwagger(ignore=true)} — a greedy {@code /htdocs/*} blob
- * handler is not API-meaningful, and emitting it as an operation just produces noise. This
- * mirrors the exclusion strategy used by the {@code BasicStaticFilesResource} mixin and keeps
- * legacy {@code BasicRestServlet}-hosted apps consistent with mixin-based static-file mounts.
- *
- * @param path The path to retrieve.
- * @param locale The locale of the HTTP request.
- * @return An HTTP resource representing the static file.
- */
- @RestGet(
- path="/htdocs/*",
- summary="Static files",
- description="Static file retrieval.",
- swagger=@OpSwagger(ignore=true)
- ) HttpResource getHtdoc(@Path String path, Locale locale);
-
- /**
- * [GET /stats] - Timing statistics.
- *
- * <p>
- * Timing statistics for method invocations on this resource.
- *
- * @param req The HTTP request.
- * @return A collection of timing statistics for each annotated method on this resource.
- */
- @RestGet(
- path="/stats",
- summary="Timing statistics",
- description="Timing statistics for method invocations on this resource."
- )
- @HtmlDocConfig(
- // Should override config annotations defined on class.
- rank=10,
- // Override the nav links for the swagger page.
- navlinks = { "back: servlet:/", "json: servlet:/stats?Accept=text/json&plainText=true" },
- // Never show aside contents of page inherited from class.
- aside="NONE"
- )
- RestContextStats getStats(RestRequest req);
-}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResource.java
similarity index 55%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObject.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResource.java
index 711e55bc6e..31cd776ec8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObject.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResource.java
@@ -16,16 +16,13 @@
*/
package org.apache.juneau.rest.servlet;
-import java.util.*;
-
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.config.*;
+import org.apache.juneau.rest.convention.*;
import org.apache.juneau.rest.docs.*;
-import org.apache.juneau.rest.stats.*;
+import org.apache.juneau.rest.ops.*;
import jakarta.servlet.http.*;
@@ -40,9 +37,10 @@ import jakarta.servlet.http.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations}, plus the api-docs
- * mixin pack ({@link BasicSwaggerUiResource} and {@link BasicRedocResource}, which transitively
- * pull in {@link BasicSwaggerResource} and {@link BasicOpenApiResource}). Resulting endpoints:
+ * The residual cross-cutting endpoints are supplied by single-responsibility op-mixins ({@link ErrorMixin},
+ * {@link HtdocMixin}, {@link StatsMixin}, and {@link FaviconMixin}), and the api-docs surface by the
+ * api-docs mixin pack ({@link SwaggerUiMixin} and {@link RedocMixin}, which transitively pull in
+ * {@link SwaggerMixin} and {@link OpenApiMixin}). Resulting endpoints:
* {@code /api}, {@code /swagger}, {@code /openapi}, {@code /openapi.json}, {@code /openapi.yaml},
* {@code /redoc}, {@code /htdocs/*}, {@code /favicon.ico}, {@code /stats}, {@code /error}.
*
@@ -50,24 +48,25 @@ import jakarta.servlet.http.*;
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestAnnotatedClassBasics">@Rest-Annotated Class Basics</a>
* </ul>
*/
-@Rest(mixins={BasicSwaggerUiResource.class, BasicRedocResource.class})
-public abstract class BasicRestObject extends RestObject implements BasicRestOperations, BasicUniversalConfig {
- @Override /* Overridden from BasicRestOperations */
- public void error() {}
-
- @Override /* Overridden from BasicRestOperations */
- public HttpResource getFavIcon() {
- String favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
- return getHtdoc(favIcon, null);
- }
-
- @Override /* Overridden from BasicRestOperations */
- public HttpResource getHtdoc(@Path("/*") String path, Locale locale) throws NotFound {
- return getContext().getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
- }
-
- @Override /* Overridden from BasicRestOperations */
- public RestContextStats getStats(RestRequest req) {
- return req.getContext().getStats();
+// @formatter:off
+@Rest(mixins={SwaggerUiMixin.class, RedocMixin.class, ErrorMixin.class, HtdocMixin.class, StatsMixin.class, FaviconMixin.class})
+@HtmlDocConfig(
+ // Basic page navigation links.
+ navlinks={
+ "up: request:/..",
+ "api: servlet:/api",
+ "stats: servlet:/stats"
}
-}
\ No newline at end of file
+)
+@JsonSchemaConfig(
+ // Add descriptions to the following types when not specified:
+ addDescriptionsTo="bean,collection,array,map,enum",
+ // Add example to the following types:
+ addExamplesTo="bean,collection,array,map",
+ // Don't generate schema information on the Swagger / OpenApi beans themselves or HTML beans.
+ ignoreTypes="Swagger,OpenApi,org.apache.juneau.bean.html5.*",
+ // Use $ref references for bean definitions to reduce duplication in generated specs.
+ useBeanDefs="true"
+)
+// @formatter:on
+public abstract class BasicRestResource extends RestResource implements BasicUniversalConfig {}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObjectGroup.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResourceGroup.java
similarity index 84%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObjectGroup.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResourceGroup.java
index 4ee3801363..2060d99a69 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestObjectGroup.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestResourceGroup.java
@@ -18,6 +18,7 @@ package org.apache.juneau.rest.servlet;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.beans.*;
import org.apache.juneau.rest.config.*;
import jakarta.servlet.*;
@@ -34,7 +35,10 @@ import jakarta.servlet.http.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations} and {@link BasicGroupOperations}.
+ * Adds the group-navigation endpoint ({@code GET /}) as a concrete method on top of the residual op-mixins
+ * inherited from {@link BasicRestResource}. The navigation page is rendered as a method of the host resource
+ * (rather than a sub-context mixin) so it inherits the host's {@link org.apache.juneau.html.annotation.HtmlDocConfig @HtmlDocConfig}
+ * page decoration.
*
* <p>
* Children are attached to this resource using the {@link Rest#children() @Rest(children)} annotation.
@@ -52,7 +56,22 @@ import jakarta.servlet.http.*;
* </ul>
*/
@Rest
-public abstract class BasicRestObjectGroup extends BasicRestObject implements BasicGroupOperations {
+public abstract class BasicRestResourceGroup extends BasicRestResource {
+
+ /**
+ * [GET /] - Get child resources.
+ *
+ * <p>
+ * Returns a bean that lists and allows navigation to child resources. Default implementation
+ * delegates to {@link ChildResourceDescriptions#of(RestRequest)}; subclasses may override.
+ *
+ * @param req The HTTP request.
+ * @return The bean containing links to the child resources.
+ */
+ @RestGet(path="/", summary="Navigation page")
+ public ChildResourceDescriptions getChildren(RestRequest req) {
+ return ChildResourceDescriptions.of(req);
+ }
/**
* Returns the {@link RestChildren} registry backing this group resource.
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServlet.java
index 492d8a0f88..ef42cc857a 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServlet.java
@@ -16,19 +16,16 @@
*/
package org.apache.juneau.rest.servlet;
-import java.util.*;
-
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.http.response.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.jsonschema.annotation.*;
import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.config.*;
+import org.apache.juneau.rest.convention.*;
import org.apache.juneau.rest.docs.*;
-import org.apache.juneau.rest.stats.*;
+import org.apache.juneau.rest.ops.*;
/**
- * Subclass of {@link RestServlet} with default settings and standard methods defined.
+ * Subclass of {@link RestServlet} with default settings and standard endpoints defined.
*
* <p>
* Meant as a base class for top-level REST resources in servlet containers.
@@ -38,9 +35,10 @@ import org.apache.juneau.rest.stats.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations}, plus the api-docs
- * mixin pack ({@link BasicSwaggerUiResource} and {@link BasicRedocResource}, which transitively
- * pull in {@link BasicSwaggerResource} and {@link BasicOpenApiResource}). Resulting endpoints:
+ * The residual cross-cutting endpoints are supplied by single-responsibility op-mixins ({@link ErrorMixin},
+ * {@link HtdocMixin}, {@link StatsMixin}, and {@link FaviconMixin}), and the api-docs surface by the
+ * api-docs mixin pack ({@link SwaggerUiMixin} and {@link RedocMixin}, which transitively pull in
+ * {@link SwaggerMixin} and {@link OpenApiMixin}). Resulting endpoints:
* {@code /api}, {@code /swagger}, {@code /openapi}, {@code /openapi.json}, {@code /openapi.yaml},
* {@code /redoc}, {@code /htdocs/*}, {@code /favicon.ico}, {@code /stats}, {@code /error}.
*
@@ -50,26 +48,27 @@ import org.apache.juneau.rest.stats.*;
*
* @serial exclude
*/
-@Rest(mixins={BasicSwaggerUiResource.class, BasicRedocResource.class})
-public abstract class BasicRestServlet extends RestServlet implements BasicRestOperations, BasicUniversalConfig {
- private static final long serialVersionUID = 1L;
-
- @Override /* Overridden from BasicRestOperations */
- public void error() {}
-
- @Override /* Overridden from BasicRestOperations */
- public HttpResource getFavIcon() {
- String favIcon = getContext().getConfig().get("REST/favicon").orElse("images/juneau.png");
- return getHtdoc(favIcon, null);
+// @formatter:off
+@Rest(mixins={SwaggerUiMixin.class, RedocMixin.class, ErrorMixin.class, HtdocMixin.class, StatsMixin.class, FaviconMixin.class})
+@HtmlDocConfig(
+ // Basic page navigation links.
+ navlinks={
+ "up: request:/..",
+ "api: servlet:/api",
+ "stats: servlet:/stats"
}
-
- @Override /* Overridden from BasicRestOperations */
- public HttpResource getHtdoc(@Path("/*") String path, Locale locale) throws NotFound {
- return getContext().getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
- }
-
- @Override /* Overridden from BasicRestOperations */
- public RestContextStats getStats(RestRequest req) {
- return req.getContext().getStats();
- }
-}
\ No newline at end of file
+)
+@JsonSchemaConfig(
+ // Add descriptions to the following types when not specified:
+ addDescriptionsTo="bean,collection,array,map,enum",
+ // Add example to the following types:
+ addExamplesTo="bean,collection,array,map",
+ // Don't generate schema information on the Swagger / OpenApi beans themselves or HTML beans.
+ ignoreTypes="Swagger,OpenApi,org.apache.juneau.bean.html5.*",
+ // Use $ref references for bean definitions to reduce duplication in generated specs.
+ useBeanDefs="true"
+)
+// @formatter:on
+public abstract class BasicRestServlet extends RestServlet implements BasicUniversalConfig {
+ private static final long serialVersionUID = 1L;
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServletGroup.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServletGroup.java
index 46316db13a..a7163e13a9 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServletGroup.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/BasicRestServletGroup.java
@@ -18,6 +18,7 @@ package org.apache.juneau.rest.servlet;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.beans.*;
import org.apache.juneau.rest.config.*;
import jakarta.servlet.*;
@@ -33,7 +34,10 @@ import jakarta.servlet.*;
* for details.
*
* <p>
- * Implements the basic REST endpoints defined in {@link BasicRestOperations} and {@link BasicGroupOperations}.
+ * Adds the group-navigation endpoint ({@code GET /}) as a concrete method on top of the residual op-mixins
+ * inherited from {@link BasicRestServlet}. The navigation page is rendered as a method of the host resource
+ * (rather than a sub-context mixin) so it inherits the host's {@link org.apache.juneau.html.annotation.HtmlDocConfig @HtmlDocConfig}
+ * page decoration.
*
* <p>
* Children are attached to this resource using the {@link Rest#children() @Rest(children)} annotation.
@@ -53,9 +57,24 @@ import jakarta.servlet.*;
* @serial exclude
*/
@Rest
-public abstract class BasicRestServletGroup extends BasicRestServlet implements BasicGroupOperations {
+public abstract class BasicRestServletGroup extends BasicRestServlet {
private static final long serialVersionUID = 1L;
+ /**
+ * [GET /] - Get child resources.
+ *
+ * <p>
+ * Returns a bean that lists and allows navigation to child resources. Default implementation
+ * delegates to {@link ChildResourceDescriptions#of(RestRequest)}; subclasses may override.
+ *
+ * @param req The HTTP request.
+ * @return The bean containing links to the child resources.
+ */
+ @RestGet(path="/", summary="Navigation page")
+ public ChildResourceDescriptions getChildren(RestRequest req) {
+ return ChildResourceDescriptions.of(req);
+ }
+
/**
* Returns the {@link RestChildren} registry backing this group resource.
*
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestMixin.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestMixin.java
new file mode 100644
index 0000000000..d97cd3eb16
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestMixin.java
@@ -0,0 +1,58 @@
+/*
+ * 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.rest.servlet;
+
+import org.apache.juneau.rest.annotation.*;
+
+/**
+ * Optional base class for <c>@Rest</c> mixin classes — the third sibling of {@link RestServlet}
+ * (servlet flavor) and {@link RestResource} (child-resource flavor), completing the
+ * servlet / resource / mixin naming triad.
+ *
+ * <p>
+ * A <i>mixin</i> is a plain {@link Rest @Rest}-annotated POJO whose {@code @RestOp} methods are pulled
+ * into a host servlet/resource context when the host declares
+ * {@link Rest#mixins() @Rest(mixins=ThatMixin.class)}. Mixins compose through the existing sub-context
+ * model; {@code RestMixin} does <b>not</b> change that composition mechanism.
+ *
+ * <h5 class='section'>Opt-in, not mandatory:</h5>
+ *
+ * <p>
+ * Extending {@code RestMixin} is <b>optional</b>. A bare {@code @Rest} POJO with no base class remains a
+ * fully-supported mixin (annotation-only configuration), exactly as before — the framework reads
+ * such mixins reflectively. Capability mixins that ship without state (e.g. the api-docs pack) stay
+ * base-less; the new single-responsibility op-mixins extend this base to make the triad membership
+ * explicit.
+ *
+ * <h5 class='section'>Builder support (deferred):</h5>
+ *
+ * <p>
+ * The fluent programmatic-builder surface ({@code RestBuilder}/{@code RestMixin.Builder}) that would let
+ * a mixin be configured programmatically rather than by annotation is <b>not</b> part of this base yet
+ * — it is deferred along with the resource/servlet builder work. Until then, {@code RestMixin}
+ * carries no builder or stashed-builder state and mixins are configured purely by their {@code @Rest} /
+ * {@code @RestOp} annotations.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jc'>{@link RestServlet}
+ * <li class='jc'>{@link RestResource}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+public abstract class RestMixin {}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestResource.java
similarity index 99%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestResource.java
index bb277b13fc..69c72d48a3 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestObject.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/servlet/RestResource.java
@@ -41,7 +41,7 @@ import jakarta.servlet.http.*;
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestAnnotatedClassBasics">@Rest-Annotated Class Basics</a>
* </ul>
*/
-public abstract class RestObject {
+public abstract class RestResource {
private AtomicReference<RestContext> context = new AtomicReference<>();
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesMixin.java
similarity index 95%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesResource.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesMixin.java
index 28a7162aa0..afcff8157c 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesResource.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesMixin.java
@@ -31,7 +31,7 @@ import org.apache.juneau.rest.annotation.*;
* <p>
* Wraps the existing {@link BasicStaticFiles} plumbing (a {@link StaticFiles} implementation, not a
* servlet) in a servlet-level mixin so any Juneau resource can opt into static-file serving via
- * {@link Rest#mixins() @Rest(mixins=BasicStaticFilesResource.class)}. The mixin reads the active
+ * {@link Rest#mixins() @Rest(mixins=StaticFilesMixin.class)}. The mixin reads the active
* {@link StaticFiles} from the bean store at request time — importer's
* {@code @Bean StaticFiles} declarations + classpath defaults are picked up automatically.
*
@@ -74,7 +74,7 @@ import org.apache.juneau.rest.annotation.*;
*
* <p class='bjava'>
* <jc>// Vanilla resource gains static-file serving at /static/*.</jc>
- * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=BasicStaticFilesResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/api"</js>, mixins=StaticFilesMixin.<jk>class</jk>)
* <jk>public class</jk> ApiResource <jk>extends</jk> RestServlet {
* <ja>@RestGet</ja>(<js>"/items"</js>) <jk>public</jk> List<Item> items() { ... }
* }
@@ -84,7 +84,7 @@ import org.apache.juneau.rest.annotation.*;
*
* <ul class='spaced-list'>
* <li>GET hits the active {@link StaticFiles} bean (resolved via
- * {@link RestRequest#getStaticFiles()}); missing paths surface as
+ * {@link RestContext#getStaticFiles()}); missing paths surface as
* {@link NotFound} thrown from the handler.
* <li>{@code HEAD} requests are accepted via the standard servlet
* {@code HEAD}-via-{@code GET} contract: the response carries identical headers to the
@@ -129,7 +129,7 @@ import org.apache.juneau.rest.annotation.*;
*/
// @formatter:off
@Rest
-public class BasicStaticFilesResource {
+public class StaticFilesMixin {
/**
* [GET /static/*] — serve a static file from the active {@link StaticFiles} bean.
@@ -140,7 +140,7 @@ public class BasicStaticFilesResource {
* {@link StaticFiles#resolve(String,Locale) StaticFiles.resolve(...)} so localized lookups
* (e.g. {@code styles_fr.css}) work out of the box.
*
- * @param req The current REST request — supplies {@link RestRequest#getStaticFiles()}.
+ * @param req The current REST request — supplies {@link RestContext#getStaticFiles()}.
* @param path The trailing remainder after the mount prefix (the file path within the
* {@code static/} or {@code htdocs/} classpath / filesystem search roots).
* @param locale The request locale (used for localized resource lookups).
@@ -154,7 +154,7 @@ public class BasicStaticFilesResource {
swagger=@OpSwagger(ignore=true)
)
public HttpResource getStaticFile(RestRequest req, @Path("/*") String path, Locale locale) {
- return req.getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
+ return req.getContext().getStaticFiles().resolve(path, locale).orElseThrow(NotFound::new);
}
/**
@@ -167,7 +167,7 @@ public class BasicStaticFilesResource {
* at the response-processor layer based on {@link RestRequest#getMethod()}, so this handler can
* delegate to {@link #getStaticFile} verbatim.
*
- * @param req The current REST request — supplies {@link RestRequest#getStaticFiles()}.
+ * @param req The current REST request — supplies {@link RestContext#getStaticFiles()}.
* @param path The trailing remainder after the mount prefix.
* @param locale The request locale (used for localized resource lookups).
* @return The matching {@link HttpResource} (with headers; body suppressed by the processor).
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesResource.java
similarity index 65%
copy from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java
copy to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesResource.java
index c97d1173f9..a597bc4873 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesResource.java
@@ -26,58 +26,48 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicStaticFilesResource} mixin.
+ * Child-resource flavor of the static-files capability.
*
* <p>
- * Mounts as a <b>sibling top-level servlet</b> at {@code /static/*} and serves static files from the
- * active {@link StaticFiles} bean by delegating to a shared {@link BasicStaticFilesResource}
- * instance — the same logic the mixin uses, so the two forms cannot drift.
+ * Mounts as a <b>routed child</b> via {@link Rest#children() @Rest(children=StaticFilesResource.class)}
+ * under a parent at the subtree {@code /static} and serves static files from the active
+ * {@link StaticFiles} bean by delegating to a shared {@link StaticFilesMixin} instance — the same
+ * logic the mixin and {@link StaticFilesServlet servlet} flavors use, so the three forms cannot drift.
*
* <p>
- * Whereas the {@link BasicStaticFilesResource} mixin pins its op at {@code /static/*} for composition
- * into a host at {@code /}, this companion declares the mount at the class level
- * ({@link Rest#paths() @Rest(paths="/static/*")}) and pins the ops at {@code /*} — eliminating
- * the path-doubling that a mixin-shaped op would produce when the servlet itself is mounted at
- * {@code /static/*}.
- *
- * <h5 class='figure'>Microservice registration:</h5>
- *
- * <p class='bjava'>
- * <ja>@Bean</ja> Servlet staticFiles() {
- * <jk>return new</jk> BasicStaticFilesServlet(); <jc>// auto-mounted at /static/* by JettyServerComponent</jc>
- * }
- * </p>
+ * Whereas the {@link StaticFilesMixin} mixin pins its op at {@code /static/*} to merge into a host's
+ * namespace, this child declares the subtree at the class level ({@link Rest#path() @Rest(path="/static")})
+ * and pins the ops at {@code /*} — the op must <b>not</b> re-pin {@code /static/*} or it would
+ * double-path to {@code /static/static/*} under the routed-subtree wiring.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicStaticFilesResource}
+ * <li class='jc'>{@link StaticFilesMixin}
+ * <li class='jc'>{@link StaticFilesServlet}
* <li class='jc'>{@link StaticFiles}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/StaticFiles">Static files</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
*
- * @serial exclude
* @since 9.5.0
*/
// @formatter:off
-@Rest(paths="/static/*")
-public class BasicStaticFilesServlet extends RestServlet {
-
- private static final long serialVersionUID = 1L;
+@Rest(path="/static")
+public class StaticFilesResource extends RestResource {
- private final transient BasicStaticFilesResource delegate;
+ private final transient StaticFilesMixin delegate;
- /** No-arg constructor — uses a default {@link BasicStaticFilesResource} delegate. */
- public BasicStaticFilesServlet() {
- this(new BasicStaticFilesResource());
+ /** No-arg constructor — uses a default {@link StaticFilesMixin} delegate. */
+ public StaticFilesResource() {
+ this(new StaticFilesMixin());
}
/**
* Delegate constructor.
*
- * @param delegate The shared static-files mixin this servlet delegates to. Must not be
+ * @param delegate The shared static-files mixin this child delegates to. Must not be
* {@code null}.
*/
- protected BasicStaticFilesServlet(BasicStaticFilesResource delegate) {
+ protected StaticFilesResource(StaticFilesMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesServlet.java
similarity index 84%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesServlet.java
index c97d1173f9..0a2269d6af 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/BasicStaticFilesServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/staticfile/StaticFilesServlet.java
@@ -26,15 +26,15 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.servlet.*;
/**
- * Standalone servlet companion of the {@link BasicStaticFilesResource} mixin.
+ * Standalone servlet companion of the {@link StaticFilesMixin} mixin.
*
* <p>
* Mounts as a <b>sibling top-level servlet</b> at {@code /static/*} and serves static files from the
- * active {@link StaticFiles} bean by delegating to a shared {@link BasicStaticFilesResource}
+ * active {@link StaticFiles} bean by delegating to a shared {@link StaticFilesMixin}
* instance — the same logic the mixin uses, so the two forms cannot drift.
*
* <p>
- * Whereas the {@link BasicStaticFilesResource} mixin pins its op at {@code /static/*} for composition
+ * Whereas the {@link StaticFilesMixin} mixin pins its op at {@code /static/*} for composition
* into a host at {@code /}, this companion declares the mount at the class level
* ({@link Rest#paths() @Rest(paths="/static/*")}) and pins the ops at {@code /*} — eliminating
* the path-doubling that a mixin-shaped op would produce when the servlet itself is mounted at
@@ -44,12 +44,12 @@ import org.apache.juneau.rest.servlet.*;
*
* <p class='bjava'>
* <ja>@Bean</ja> Servlet staticFiles() {
- * <jk>return new</jk> BasicStaticFilesServlet(); <jc>// auto-mounted at /static/* by JettyServerComponent</jc>
+ * <jk>return new</jk> StaticFilesServlet(); <jc>// auto-mounted at /static/* by JettyServerComponent</jc>
* }
* </p>
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicStaticFilesResource}
+ * <li class='jc'>{@link StaticFilesMixin}
* <li class='jc'>{@link StaticFiles}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/StaticFiles">Static files</a>
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
@@ -60,15 +60,15 @@ import org.apache.juneau.rest.servlet.*;
*/
// @formatter:off
@Rest(paths="/static/*")
-public class BasicStaticFilesServlet extends RestServlet {
+public class StaticFilesServlet extends RestServlet {
private static final long serialVersionUID = 1L;
- private final transient BasicStaticFilesResource delegate;
+ private final transient StaticFilesMixin delegate;
- /** No-arg constructor — uses a default {@link BasicStaticFilesResource} delegate. */
- public BasicStaticFilesServlet() {
- this(new BasicStaticFilesResource());
+ /** No-arg constructor — uses a default {@link StaticFilesMixin} delegate. */
+ public StaticFilesServlet() {
+ this(new StaticFilesMixin());
}
/**
@@ -77,7 +77,7 @@ public class BasicStaticFilesServlet extends RestServlet {
* @param delegate The shared static-files mixin this servlet delegates to. Must not be
* {@code null}.
*/
- protected BasicStaticFilesServlet(BasicStaticFilesResource delegate) {
+ protected StaticFilesServlet(StaticFilesMixin delegate) {
this.delegate = delegate;
}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java
index f18ec3bc42..f9d1c3f236 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/vars/FileVar.java
@@ -29,7 +29,7 @@ import org.apache.juneau.commons.svl.*;
* The format for this var is <js>"$F{path[,defaultValue]}"</js>.
*
* <p>
- * Contents of files are retrieved from the request using {@link RestRequest#getStaticFiles()}.
+ * Contents of files are retrieved from the resource context using {@link RestContext#getStaticFiles()}.
* <p>
* Localized resources (based on the locale of the HTTP request) are supported.
@@ -84,7 +84,7 @@ public class FileVar extends DefaultingVar {
RestRequest req = session.getBean(RestRequest.class).orElseThrow(InternalServerError::new);
- String s = req.getStaticFiles().getString(key, null).orElse(null);
+ String s = req.getContext().getStaticFiles().getString(key, null).orElse(null);
if (s == null)
return null;
String subType = getFileExtension(key);
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/RawTemplateDispatcher.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/RawTemplateDispatcher.java
index f81f5f71c6..e4bf103b0a 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/RawTemplateDispatcher.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/RawTemplateDispatcher.java
@@ -31,10 +31,10 @@ import org.apache.juneau.rest.*;
* {@code .html} template directly by its trailing request path.
*
* <p>
- * The per-engine mixin resources ({@code BasicJspResource}, {@code BasicFreemarkerResource},
- * {@code BasicMustacheResource}, {@code BasicThymeleafResource}) implement this interface so the
+ * The per-engine mixin resources ({@code JspMixin}, {@code FreemarkerMixin},
+ * {@code MustacheMixin}, {@code ThymeleafMixin}) implement this interface so the
* raw dispatch they already perform can be reused verbatim by their {@code Basic*Servlet} standalone
- * companions through {@link BasicViewServlet}. Sharing a single implementation means the standalone
+ * companions through {@link ViewServlet}. Sharing a single implementation means the standalone
* and mixin forms cannot drift in their file-serving behavior.
*
* <p>
@@ -44,7 +44,7 @@ import org.apache.juneau.rest.*;
* output directly onto the response.
*
* <h5 class='section'>See Also:</h5><ul>
- * <li class='jc'>{@link BasicViewServlet}
+ * <li class='jc'>{@link ViewServlet}
* <li class='jic'>{@link ViewRenderer}
* <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
* </ul>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/View.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/View.java
index 4114c9b27f..1cd58cc2a5 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/View.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/View.java
@@ -41,7 +41,7 @@ import org.apache.juneau.rest.processor.*;
* <h5 class='figure'>End-state usage:</h5>
*
* <p class='bjava'>
- * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=BasicJspResource.<jk>class</jk>)
+ * <ja>@Rest</ja>(path=<js>"/app"</js>, mixins=JspMixin.<jk>class</jk>)
* <jk>public class</jk> AppResource <jk>extends</jk> RestServlet {
*
* <ja>@RestGet</ja>(<js>"/hello/{name}"</js>)
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewResource.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewResource.java
new file mode 100644
index 0000000000..beed2793e3
--- /dev/null
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewResource.java
@@ -0,0 +1,81 @@
+/*
+ * 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.rest.view;
+
+import java.io.*;
+
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.servlet.*;
+
+/**
+ * Abstract base for the child-resource flavors of the view mixin resources.
+ *
+ * <p>
+ * Mirror of {@link ViewServlet} for routed-child deployment: each per-engine bridge module ships a thin
+ * {@code <Engine>Resource} subclass that declares its own subtree mount via
+ * {@link Rest#path() @Rest(path)} (e.g. {@code "/jsp"}) and supplies the per-engine
+ * {@link RawTemplateDispatcher} (the matching {@code <Engine>Mixin} instance) via {@link #dispatcher()}.
+ *
+ * <p>
+ * The single greedy op declared here ({@code @RestGet(path="/*")}) captures the trailing remainder under
+ * the child's subtree mount and delegates straight to the shared {@link RawTemplateDispatcher}, so the
+ * mixin, servlet, and child forms cannot drift.
+ *
+ * <h5 class='section'>See Also:</h5><ul>
+ * <li class='jic'>{@link RawTemplateDispatcher}
+ * <li class='jc'>{@link ViewServlet}
+ * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestServerComposition">REST Server — Composition (mixins, paths)</a>
+ * </ul>
+ *
+ * @since 9.5.0
+ */
+@Rest
+public abstract class ViewResource extends RestResource {
+
+ /**
+ * Returns the per-engine {@link RawTemplateDispatcher} this child delegates raw template dispatch
+ * to.
+ *
+ * <p>
+ * Typically the matching {@code <Engine>Mixin} instance (which implements
+ * {@link RawTemplateDispatcher}). Never {@code null}.
+ *
+ * @return The raw-template dispatcher. Never {@code null}.
+ */
+ protected abstract RawTemplateDispatcher dispatcher();
+
+ /**
+ * [GET /*] — render the raw template identified by the trailing path under this child's
+ * subtree mount.
+ *
+ * @param path The trailing path segment after the mount prefix.
+ * @param req The current REST request.
+ * @param res The current REST response.
+ * @throws IOException If the underlying response writer fails.
+ */
+ @RestGet(
+ path="/*",
+ summary="View",
+ description="Render a raw template under this child's subtree mount.",
+ swagger=@OpSwagger(ignore=true)
+ )
+ public void render(@Path("/*") String path, RestRequest req, RestResponse res) throws IOException {
+ dispatcher().render(path, req, res);
+ }
+}
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/BasicViewServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewServlet.java
similarity index 98%
rename from juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/BasicViewServlet.java
rename to juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewServlet.java
index 99d9b1797e..3b7d505f9f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/BasicViewServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/view/ViewServlet.java
@@ -63,7 +63,7 @@ import org.apache.juneau.rest.servlet.*;
* @since 9.5.0
*/
@Rest
-public abstract class BasicViewServlet extends RestServlet {
+public abstract class ViewServlet extends RestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
index c07085f905..7cd01f5d47 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/Widget.java
@@ -136,7 +136,7 @@ public abstract class Widget implements HtmlWidget {
* @return The file finder to used for finding files on the file system.
*/
protected FileFinder getFileFinder(RestRequest req) {
- return req.getStaticFiles();
+ return req.getContext().getStaticFiles();
}
/**
diff --git a/juneau-utest/src/test/java/org/apache/juneau/commons/inject/Value_SupplierTypedFieldType_Test.java b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/Value_SupplierTypedFieldType_Test.java
new file mode 100644
index 0000000000..f02e138a1c
--- /dev/null
+++ b/juneau-utest/src/test/java/org/apache/juneau/commons/inject/Value_SupplierTypedFieldType_Test.java
@@ -0,0 +1,269 @@
+/*
+ * 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.commons.inject;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.net.*;
+import java.nio.file.*;
+import java.time.*;
+import java.util.function.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.commons.settings.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * Verifies the typed {@code @Value Supplier<T>} autodetect contract — the extension of the bare
+ * {@code Supplier<String>} path so that {@code T != String} is coerced from the resolved string
+ * using the same converter machinery plain {@code @Value T} uses.
+ *
+ * <ul>
+ * <li>{@code Supplier<T>} for the common converter targets (Integer, Long, Boolean, Duration, URI,
+ * enum) resolve and coerce correctly.
+ * <li>Each {@code .get()} re-resolves the string <i>and</i> re-coerces — live config changes are
+ * reflected (the coerced value is never memoized).
+ * <li>A coercion failure surfaces as a {@link RuntimeException} from {@code .get()}.
+ * <li>{@code Supplier<String>} and raw {@code Supplier} behavior is unchanged.
+ * <li>{@code Optional<Supplier<T>>} nesting is not specially handled.
+ * </ul>
+ */
+class Value_SupplierTypedFieldType_Test extends TestBase {
+
+ private static final String P_KEY = "Value_SupplierTypedFieldType_Test.key";
+
+ private BasicBeanStore beanStore;
+
+ @BeforeEach
+ void setUp() {
+ beanStore = new BasicBeanStore(null);
+ }
+
+ @AfterEach
+ void cleanup() {
+ Settings.get().unsetGlobal(P_KEY);
+ ValueResolver.clearTemplateCache();
+ }
+
+ enum A07_Color { RED, GREEN, BLUE }
+
+ public static class IntegerSupplierBean {
+ @Value("${" + P_KEY + ":42}")
+ Supplier<Integer> value;
+ }
+
+ public static class LongSupplierBean {
+ @Value("${" + P_KEY + ":42}")
+ Supplier<Long> value;
+ }
+
+ public static class BooleanSupplierBean {
+ @Value("${" + P_KEY + ":true}")
+ Supplier<Boolean> value;
+ }
+
+ public static class DurationSupplierBean {
+ @Value("${" + P_KEY + ":PT30S}")
+ Supplier<Duration> value;
+ }
+
+ public static class UriSupplierBean {
+ @Value("${" + P_KEY + ":https://example.org/}")
+ Supplier<URI> value;
+ }
+
+ public static class EnumSupplierBean {
+ @Value("${" + P_KEY + ":RED}")
+ Supplier<A07_Color> value;
+ }
+
+ public static class PathSupplierBean {
+ @Value("${" + P_KEY + ":/tmp/x}")
+ Supplier<Path> value;
+ }
+
+ public static class StringSupplierBean {
+ @Value("${" + P_KEY + ":default}")
+ Supplier<String> value;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public static class RawSupplierBean {
+ @Value("${" + P_KEY + ":default}")
+ Supplier value;
+ }
+
+ public static class OptionalSupplierBean {
+ @Value("${" + P_KEY + ":42}")
+ java.util.Optional<Supplier<Integer>> value;
+ }
+
+ public static class IntegerSupplierCtorBean {
+ final Supplier<Integer> value;
+
+ @Inject
+ public IntegerSupplierCtorBean(@Value("${" + P_KEY + ":42}") Supplier<Integer> value) {
+ this.value = value;
+ }
+ }
+
+ //====================================================================================================
+ // a — one typed-supplier test per converter category.
+ //====================================================================================================
+
+ @Test void a01_integer() {
+ Settings.get().setGlobal(P_KEY, "1234");
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ assertEquals(Integer.valueOf(1234), bean.value.get());
+ }
+
+ @Test void a02_long() {
+ Settings.get().setGlobal(P_KEY, "9999999999");
+ var bean = BeanInstantiator.of(LongSupplierBean.class, beanStore).run();
+ assertEquals(Long.valueOf(9999999999L), bean.value.get());
+ }
+
+ @Test void a03_boolean() {
+ Settings.get().setGlobal(P_KEY, "true");
+ var bean = BeanInstantiator.of(BooleanSupplierBean.class, beanStore).run();
+ assertEquals(Boolean.TRUE, bean.value.get());
+ }
+
+ @Test void a04_duration() {
+ Settings.get().setGlobal(P_KEY, "PT1M");
+ var bean = BeanInstantiator.of(DurationSupplierBean.class, beanStore).run();
+ assertEquals(Duration.ofMinutes(1), bean.value.get());
+ }
+
+ @Test void a05_uri() {
+ Settings.get().setGlobal(P_KEY, "https://juneau.apache.org/");
+ var bean = BeanInstantiator.of(UriSupplierBean.class, beanStore).run();
+ assertEquals(URI.create("https://juneau.apache.org/"), bean.value.get());
+ }
+
+ @Test void a06_defaultExpression_coerced() {
+ // No Settings entry — the ${key:42} default flows through coercion the same as a resolved value.
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ assertEquals(Integer.valueOf(42), bean.value.get());
+ }
+
+ @Test void a07_enum() {
+ Settings.get().setGlobal(P_KEY, "GREEN");
+ var bean = BeanInstantiator.of(EnumSupplierBean.class, beanStore).run();
+ assertEquals(A07_Color.GREEN, bean.value.get());
+ }
+
+ @Test void a08_constructorParam() {
+ Settings.get().setGlobal(P_KEY, "777");
+ var bean = BeanInstantiator.of(IntegerSupplierCtorBean.class, beanStore).run();
+ assertEquals(Integer.valueOf(777), bean.value.get());
+ }
+
+ @Test void a09_path_registryBoundary_throwsFromGet() {
+ // Path is NOT in the String->T converter registry (it is an interface with no (String)
+ // constructor or single-arg String factory — StringSetting.asPath() special-cases Paths.get()
+ // outside of Settings.toType). The typed-supplier path deliberately reuses ONLY the registry
+ // (no hardcoded subset), so Supplier<Path> behaves identically to plain @Value Path: the
+ // coercion fails as a RuntimeException at .get() time.
+ Settings.get().setGlobal(P_KEY, "/tmp/x");
+ var bean = BeanInstantiator.of(PathSupplierBean.class, beanStore).run();
+ assertThrows(RuntimeException.class, () -> bean.value.get());
+ }
+
+ //====================================================================================================
+ // b — late binding: each .get() re-resolves AND re-coerces (no value memoization).
+ //====================================================================================================
+
+ @Test void b01_lateBinding_reCoercesPerGet() {
+ Settings.get().setGlobal(P_KEY, "1");
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ assertEquals(Integer.valueOf(1), bean.value.get());
+
+ Settings.get().setGlobal(P_KEY, "2");
+ assertEquals(Integer.valueOf(2), bean.value.get(), "Supplier<Integer> re-resolves and re-coerces per .get()");
+
+ Settings.get().setGlobal(P_KEY, "3");
+ assertEquals(Integer.valueOf(3), bean.value.get());
+ }
+
+ @Test void b02_lateBinding_notMemoizedAcrossInstances() {
+ Settings.get().setGlobal(P_KEY, "10");
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ var first = bean.value.get();
+ var second = bean.value.get();
+ // Distinct boxed instances (outside the Integer cache range) prove no value memoization.
+ Settings.get().setGlobal(P_KEY, "1000");
+ assertEquals(Integer.valueOf(10), first);
+ assertEquals(Integer.valueOf(10), second);
+ assertEquals(Integer.valueOf(1000), bean.value.get());
+ }
+
+ //====================================================================================================
+ // c — coercion failure surfaces as a RuntimeException from .get().
+ //====================================================================================================
+
+ @Test void c01_coercionFailure_throwsFromGet() {
+ Settings.get().setGlobal(P_KEY, "notAnInt");
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ assertThrows(RuntimeException.class, () -> bean.value.get());
+ }
+
+ @Test void c02_coercionFailure_messageNamesKeyAndType() {
+ Settings.get().setGlobal(P_KEY, "notAnInt");
+ var bean = BeanInstantiator.of(IntegerSupplierBean.class, beanStore).run();
+ var e = assertThrows(RuntimeException.class, () -> bean.value.get());
+ assertTrue(e.getMessage().contains("Integer"), "Message should name the target type: " + e.getMessage());
+ assertTrue(e.getMessage().contains(P_KEY), "Message should name the @Value expression: " + e.getMessage());
+ }
+
+ @Test void c03_enumCoercionFailure_throwsFromGet() {
+ Settings.get().setGlobal(P_KEY, "PURPLE");
+ var bean = BeanInstantiator.of(EnumSupplierBean.class, beanStore).run();
+ assertThrows(RuntimeException.class, () -> bean.value.get());
+ }
+
+ //====================================================================================================
+ // d — regression: Supplier<String> and raw Supplier behavior unchanged.
+ //====================================================================================================
+
+ @Test void d01_supplierString_unchanged() {
+ Settings.get().setGlobal(P_KEY, "first");
+ var bean = BeanInstantiator.of(StringSupplierBean.class, beanStore).run();
+ assertEquals("first", bean.value.get());
+
+ Settings.get().setGlobal(P_KEY, "second");
+ assertEquals("second", bean.value.get(), "Supplier<String> still re-evaluates per .get()");
+ }
+
+ @Test void d02_rawSupplier_unchanged() {
+ // Raw Supplier (no type argument) is not a coercible typed-supplier site — it falls through to
+ // the one-shot path, where Supplier.class is not a registry-known type, so injection fails.
+ Settings.get().setGlobal(P_KEY, "anything");
+ assertThrows(RuntimeException.class, () -> BeanInstantiator.of(RawSupplierBean.class, beanStore).run());
+ }
+
+ //====================================================================================================
+ // e — Optional<Supplier<T>> is not specially handled.
+ //====================================================================================================
+
+ @Test void e01_optionalOfSupplier_notSpeciallyHandled() {
+ // Optional<Supplier<Integer>> unwraps to Supplier.class but the generic type's raw is Optional,
+ // so the typed-supplier path is not taken. It is not specially supported.
+ Settings.get().setGlobal(P_KEY, "42");
+ assertThrows(RuntimeException.class, () -> BeanInstantiator.of(OptionalSupplierBean.class, beanStore).run());
+ }
+}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/commons/utils/FileUtils_ResolveSafely_Test.java b/juneau-utest/src/test/java/org/apache/juneau/commons/utils/FileUtils_ResolveSafely_Test.java
index 449caeda50..97705570a4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/commons/utils/FileUtils_ResolveSafely_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/commons/utils/FileUtils_ResolveSafely_Test.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.io.*;
*
* <p>
* The two helpers are the shared canonical implementations behind the path-traversal hardening
- * in {@code DirectoryResource}, {@code LogsResource}, and {@code BasicJspResource}; the tests
+ * in {@code DirectoryResource}, {@code LogsResource}, and {@code JspMixin}; the tests
* here exercise the shared semantic invariants directly so the per-resource regression suites
* can focus on caller-layer behavior (HTTP status codes, response shape).
*/
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/classic/SerializedHttpEntity_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/classic/SerializedHttpEntity_Test.java
index 4512d6011e..e639c61ba8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/classic/SerializedHttpEntity_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/classic/SerializedHttpEntity_Test.java
@@ -41,7 +41,7 @@ import org.junit.jupiter.api.*;
class SerializedHttpEntity_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public String[] checkHeader(org.apache.juneau.rest.RestRequest req) {
return req.getHeaders().getAll(req.getHeaderParam("Check").orElse(null)).stream().map(RequestHeader::getValue).toArray(String[]::new);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
index 749dfd99bc..d5e7bcad44 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_Test.java
@@ -530,7 +530,7 @@ class Remote_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
@Rest
- public static class F extends BasicRestObject {
+ public static class F extends BasicRestResource {
@RestGet
public String[] headers(org.apache.juneau.rest.RestRequest req) {
return req.getHeaders().getAll(req.getHeaderParam("Check").orElse(null)).stream().map(RequestHeader::getValue).toArray(String[]::new);
@@ -579,7 +579,7 @@ class Remote_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
@Rest
- public static class G extends BasicRestObject {}
+ public static class G extends BasicRestResource {}
@Remote
public interface G1 {
@@ -596,7 +596,7 @@ class Remote_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
@Rest
- public static class H extends BasicRestObject {
+ public static class H extends BasicRestResource {
@RestOp(method="*", path="/*")
public String echoMethod(@Method String method, @Path("/*") String path) {
return method + " " + path;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/NoInherit_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/NoInherit_Test.java
index 1057ee527a..95ef56df1f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/NoInherit_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/NoInherit_Test.java
@@ -26,20 +26,20 @@ import java.nio.charset.StandardCharsets;
import org.apache.juneau.TestBase;
import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.servlet.BasicRestObject;
+import org.apache.juneau.rest.servlet.BasicRestResource;
import org.junit.jupiter.api.*;
class NoInherit_Test extends TestBase {
- private static RestContext restContext(Class<? extends BasicRestObject> c) throws Exception {
+ private static RestContext restContext(Class<? extends BasicRestResource> c) throws Exception {
var o = c.getDeclaredConstructor().newInstance();
- // Check if class has a parent REST resource (not BasicRestObject)
+ // Check if class has a parent REST resource (not BasicRestResource)
RestContext parentContext = null;
var superClass = c.getSuperclass();
- if (superClass != null && superClass != BasicRestObject.class && BasicRestObject.class.isAssignableFrom(superClass)) {
+ if (superClass != null && superClass != BasicRestResource.class && BasicRestResource.class.isAssignableFrom(superClass)) {
@SuppressWarnings("unchecked")
- var parentClass = (Class<? extends BasicRestObject>) superClass;
+ var parentClass = (Class<? extends BasicRestResource>) superClass;
parentContext = restContext(parentClass);
}
@@ -47,7 +47,7 @@ class NoInherit_Test extends TestBase {
}
@Rest(allowedSerializerOptions = "parentSer")
- public static class ParentSer extends BasicRestObject {}
+ public static class ParentSer extends BasicRestResource {}
@Rest(allowedSerializerOptions = "childSer", noInherit = "allowedSerializerOptions")
public static class ChildSer extends ParentSer {}
@@ -62,7 +62,7 @@ class NoInherit_Test extends TestBase {
}
@Rest(allowedSerializerOptions = "pBoth")
- public static class ParentBoth extends BasicRestObject {}
+ public static class ParentBoth extends BasicRestResource {}
@Rest(allowedSerializerOptions = "cBoth")
public static class ChildBoth extends ParentBoth {}
@@ -76,7 +76,7 @@ class NoInherit_Test extends TestBase {
assertTrue(keys.contains("cBoth"));
}
- public static class ParentM extends BasicRestObject {
+ public static class ParentM extends BasicRestResource {
@RestGet(allowedSerializerOptions = "parentM")
public void get() {
// Intentionally empty - method only used for annotation metadata testing
@@ -109,7 +109,7 @@ class NoInherit_Test extends TestBase {
// Test case for aggregated noInherit: parent has noInherit="prop1", child has noInherit="prop2"
// The aggregated noInherit should be {"prop1", "prop2"}, but allowedSerializerOptions should
// include values from both parent and child since neither blocks allowedSerializerOptions
- public static class ParentAggregated extends BasicRestObject {
+ public static class ParentAggregated extends BasicRestResource {
@RestGet(allowedSerializerOptions = "parentOpt", noInherit = "prop1")
public void get() {
// Intentionally empty - method only used for annotation metadata testing
@@ -140,7 +140,7 @@ class NoInherit_Test extends TestBase {
// Test that noInherit blocks REST class context inheritance but NOT parent method inheritance
@Rest(allowedSerializerOptions = "classLevel")
- public static class ParentWithClassLevel extends BasicRestObject {
+ public static class ParentWithClassLevel extends BasicRestResource {
@RestGet(allowedSerializerOptions = "parentMethod")
public void get() {
// Intentionally empty - method only used for annotation metadata testing
@@ -173,7 +173,7 @@ class NoInherit_Test extends TestBase {
}
/**
- * Plain {@code @Rest} POJO (not {@link BasicRestObject}) so {@code BasicUniversalConfig} does not pre-populate
+ * Plain {@code @Rest} POJO (not {@link BasicRestResource}) so {@code BasicUniversalConfig} does not pre-populate
* charset / maxInput on the op builder — needed to exercise {@code @Rest}-hierarchy fallbacks and {@code noInherit}.
*/
@Rest(defaultCharset = "ISO-8859-1")
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_GetterShapes_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_GetterShapes_Test.java
index 694386791b..a42271bfd6 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_GetterShapes_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_GetterShapes_Test.java
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the permissive {@link Object}-typed return contract for the {@code getPaths()} virtual
- * getter on {@link RestServlet} / {@link RestObject}.
+ * getter on {@link RestServlet} / {@link RestResource}.
*
* <p>
* Since 9.5.0 the {@code getPaths()} signature returns {@link Object}, accepting any of:
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_Getter_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_Getter_Test.java
index 0e205fd624..c075cdda01 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_Getter_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/RestPathsRuntimeOverride_Getter_Test.java
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code getPaths()} virtual-getter rung of the runtime-override resolution chain on
* {@link RestContext#getPaths()}: a {@link RestServlet#getPaths() RestServlet.getPaths()} (or
- * {@link RestObject#getPaths() RestObject.getPaths()}) override beats the annotation default; a
+ * {@link RestResource#getPaths() RestResource.getPaths()}) override beats the annotation default; a
* {@code null} return falls through to the annotation; an explicit {@code new String[0]} return clears.
*
* <p>
@@ -98,16 +98,16 @@ class RestPathsRuntimeOverride_Getter_Test extends TestBase {
}
@Rest(paths={"/from-annotation"})
- public static class E_RestObjectGetter extends RestObject {
+ public static class E_RestResourceGetter extends RestResource {
@Override public String[] getPaths() { return new String[]{"/from-restobject-getter"}; }
}
@Test
void e01_restObjectGetter_overrideAnnotation() throws Exception {
- var args = new RestContext.Args(E_RestObjectGetter.class, null, null, E_RestObjectGetter::new, "", null, null, null, false);
+ var args = new RestContext.Args(E_RestResourceGetter.class, null, null, E_RestResourceGetter::new, "", null, null, null, false);
var ctx = new RestContext(args).postInit().postInitChildFirst();
assertArrayEquals(new String[]{"/from-restobject-getter"}, ctx.getPaths(),
- "RestObject.getPaths() override should also beat the annotation default");
+ "RestResource.getPaths() override should also beat the annotation default");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServletPathResolution_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServletPathResolution_Test.java
index 64e52c576d..9d216165b8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServletPathResolution_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServletPathResolution_Test.java
@@ -49,31 +49,31 @@ class StandaloneServletPathResolution_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
@Test void a01_jspServlet() {
- assertArrayEquals(new String[]{"/jsp/*"}, paths(BasicJspServlet.class, new BasicJspServlet()));
+ assertArrayEquals(new String[]{"/jsp/*"}, paths(JspServlet.class, new JspServlet()));
}
@Test void a02_freemarkerServlet() {
- assertArrayEquals(new String[]{"/freemarker/*"}, paths(BasicFreemarkerServlet.class, new BasicFreemarkerServlet()));
+ assertArrayEquals(new String[]{"/freemarker/*"}, paths(FreemarkerServlet.class, new FreemarkerServlet()));
}
@Test void a03_mustacheServlet() {
- assertArrayEquals(new String[]{"/mustache/*"}, paths(BasicMustacheServlet.class, new BasicMustacheServlet()));
+ assertArrayEquals(new String[]{"/mustache/*"}, paths(MustacheServlet.class, new MustacheServlet()));
}
@Test void a04_thymeleafServlet() {
- assertArrayEquals(new String[]{"/thymeleaf/*"}, paths(BasicThymeleafServlet.class, new BasicThymeleafServlet()));
+ assertArrayEquals(new String[]{"/thymeleaf/*"}, paths(ThymeleafServlet.class, new ThymeleafServlet()));
}
@Test void a05_staticFilesServlet() {
- assertArrayEquals(new String[]{"/static/*"}, paths(BasicStaticFilesServlet.class, new BasicStaticFilesServlet()));
+ assertArrayEquals(new String[]{"/static/*"}, paths(StaticFilesServlet.class, new StaticFilesServlet()));
}
@Test void a06_versionServlet() {
- assertArrayEquals(new String[]{"/version/*"}, paths(BasicVersionServlet.class, new BasicVersionServlet()));
+ assertArrayEquals(new String[]{"/version/*"}, paths(VersionServlet.class, new VersionServlet()));
}
@Test void a07_adminServlet() {
- assertArrayEquals(new String[]{"/admin/*"}, paths(BasicAdminServlet.class, new BasicAdminServlet()));
+ assertArrayEquals(new String[]{"/admin/*"}, paths(AdminServlet.class, new AdminServlet()));
}
//-----------------------------------------------------------------------------------------------------------------
@@ -81,14 +81,14 @@ class StandaloneServletPathResolution_Test extends TestBase {
//-----------------------------------------------------------------------------------------------------------------
@Test void b01_versionMixin_noTopLevelPaths() {
- assertEquals(0, paths(BasicVersionResource.class, new BasicVersionResource()).length);
+ assertEquals(0, paths(VersionMixin.class, new VersionMixin()).length);
}
@Test void b02_adminMixin_noTopLevelPaths() {
- assertEquals(0, paths(BasicAdminResource.class, new BasicAdminResource()).length);
+ assertEquals(0, paths(AdminMixin.class, new AdminMixin()).length);
}
@Test void b03_staticFilesMixin_noTopLevelPaths() {
- assertEquals(0, paths(BasicStaticFilesResource.class, new BasicStaticFilesResource()).length);
+ assertEquals(0, paths(StaticFilesMixin.class, new StaticFilesMixin()).length);
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServlets_JettyMicroservice_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServlets_JettyMicroservice_Test.java
index 8f700c067e..127236dfbd 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServlets_JettyMicroservice_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/StandaloneServlets_JettyMicroservice_Test.java
@@ -39,9 +39,9 @@ import jakarta.servlet.*;
*
* <p>
* Boots a {@link org.apache.juneau.microservice.Microservice Microservice} on an ephemeral port and
- * mounts three standalone servlets as siblings — {@link BasicVersionServlet} at
- * {@code /version/*}, {@link BasicStaticFilesServlet} at {@code /static/*}, and
- * {@link BasicAdminServlet} at {@code /admin/*} — relying on the {@code JettyServerComponent}
+ * mounts three standalone servlets as siblings — {@link VersionServlet} at
+ * {@code /version/*}, {@link StaticFilesServlet} at {@code /static/*}, and
+ * {@link AdminServlet} at {@code /admin/*} — relying on the {@code JettyServerComponent}
* auto-discovery loop to read each servlet's {@code @Rest(paths)} via
* {@code RestContext.resolveTopLevelPaths(...)}. This is the cross-runtime parity check that the
* sibling top-level mount + op-at-{@code /*} shape resolves correctly through a real servlet
@@ -54,9 +54,9 @@ class StandaloneServlets_JettyMicroservice_Test extends TestBase {
@Configuration
public static class Config {
- @Bean(name="versionServlet") public Servlet versionServlet() { return new BasicVersionServlet(); }
- @Bean(name="staticFilesServlet") public Servlet staticFilesServlet() { return new BasicStaticFilesServlet(); }
- @Bean(name="adminServlet") public Servlet adminServlet() { return new BasicAdminServlet(); }
+ @Bean(name="versionServlet") public Servlet versionServlet() { return new VersionServlet(); }
+ @Bean(name="staticFilesServlet") public Servlet staticFilesServlet() { return new StaticFilesServlet(); }
+ @Bean(name="adminServlet") public Servlet adminServlet() { return new AdminServlet(); }
}
@RegisterExtension
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/BasicHttpRequestRetryHandler_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/BasicHttpRequestRetryHandler_Test.java
index 57776043c5..ec8c76a550 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/BasicHttpRequestRetryHandler_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/BasicHttpRequestRetryHandler_Test.java
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.*;
class BasicHttpRequestRetryHandler_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public Ok get() {
return OK;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestCallException_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestCallException_Test.java
index 545733d006..c3425b78f3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestCallException_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestCallException_Test.java
@@ -46,7 +46,7 @@ class RestCallException_Test extends TestBase {
}
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public InputStream echo(InputStream is) {
return is;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_BasicCalls_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_BasicCalls_Test.java
index ae5d399674..e4a23dd170 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_BasicCalls_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_BasicCalls_Test.java
@@ -58,7 +58,7 @@ class RestClient_BasicCalls_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestOp(path="/bean") public ABean getBean() { return bean; }
@RestOp(path="/bean") public ABean postBean(@Content ABean b) { return b; }
@RestOp(path="/bean") public ABean putBean(@Content ABean b) { return b; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Body_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Body_Test.java
index 7a7e07c4bd..ed51639e42 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Body_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Body_Test.java
@@ -34,7 +34,7 @@ import org.junit.jupiter.api.*;
class RestClient_Body_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader post(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) throws IOException {
for (var e : req.getHeaders())
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Context_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Context_Test.java
index b85044c2bd..9a20673ac8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Context_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Context_Test.java
@@ -36,7 +36,7 @@ import org.junit.jupiter.api.*;
class RestClient_Config_Context_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader echoBody(org.apache.juneau.rest.RestRequest req) throws IOException {
return req.getContent().getReader();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_MarshallingContext_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_MarshallingContext_Test.java
index d23ed3b244..c5f65acb86 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_MarshallingContext_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_MarshallingContext_Test.java
@@ -40,7 +40,7 @@ import org.apache.juneau.commons.bean.*;
class RestClient_Config_MarshallingContext_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader echoBody(org.apache.juneau.rest.RestRequest req) throws IOException {
return req.getContent().getReader();
@@ -91,7 +91,7 @@ class RestClient_Config_MarshallingContext_Test extends TestBase {
}
@Rest
- public static class A2b extends BasicRestObject {
+ public static class A2b extends BasicRestResource {
@RestPost
public Reader test(org.apache.juneau.rest.RestRequest req,org.apache.juneau.rest.RestResponse res) throws IOException {
res.setHeader("X",req.getHeaderParam("X").orElse(null));
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_OpenApi_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_OpenApi_Test.java
index 9903efc702..ff444cbe5e 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_OpenApi_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_OpenApi_Test.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.*;
class RestClient_Config_OpenApi_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader echoBody(org.apache.juneau.rest.RestRequest req) throws IOException {
return req.getContent().getReader();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Parser_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Parser_Test.java
index 8b518773de..69ff5d6d12 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Parser_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Parser_Test.java
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.*;
class RestClient_Config_Parser_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader echoBody(org.apache.juneau.rest.RestRequest req) throws IOException {
return req.getContent().getReader();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_RestClient_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_RestClient_Test.java
index b5cc302195..420be61cb9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_RestClient_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_RestClient_Test.java
@@ -70,7 +70,7 @@ class RestClient_Config_RestClient_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestOp(path="/bean")
public ABean getBean() {
return bean;
@@ -410,7 +410,7 @@ class RestClient_Config_RestClient_Test extends TestBase {
}
@Rest(partSerializer=A12a.class,partParser=A12b.class)
- public static class A12 extends BasicRestObject {
+ public static class A12 extends BasicRestResource {
@RestGet(path="/")
public Ok get(@Header(name="Foo") @Schema(cf="multi") ABean[] foo,org.apache.juneau.rest.RestRequest req,org.apache.juneau.rest.RestResponse res) throws Exception {
assertEquals(2,foo.length);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Serializer_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Serializer_Test.java
index e77103c427..915c6274b9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Serializer_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Config_Serializer_Test.java
@@ -44,7 +44,7 @@ class RestClient_Config_Serializer_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader echoBody(org.apache.juneau.rest.RestRequest req) throws IOException {
return req.getContent().getReader();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_FormData_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_FormData_Test.java
index a438684939..78c2e3525c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_FormData_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_FormData_Test.java
@@ -40,7 +40,7 @@ import org.junit.jupiter.api.*;
class RestClient_FormData_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Reader formData(org.apache.juneau.rest.RestRequest req) {
return reader(req.getFormParams().asQueryString());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Headers_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Headers_Test.java
index 6d3acd1a87..efbeeba52f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Headers_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Headers_Test.java
@@ -70,7 +70,7 @@ public class RestClient_Headers_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest(callLogger=CaptureLogger.class)
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet(allowedSerializerOptions="simple", allowedParserOptions="addBeanTypes")
public String[] headers(org.apache.juneau.rest.RestRequest req) {
return req.getHeaders().getAll(req.getHeaderParam("Check").orElse(null)).stream().map(RequestHeader::getValue).toArray(String[]::new);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_StreamClosed_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_StreamClosed_Test.java
index 00093ec7ec..2815953011 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_StreamClosed_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_StreamClosed_Test.java
@@ -56,7 +56,7 @@ import org.junit.jupiter.api.*;
class RestClient_Logging_StreamClosed_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public String hello() {
return "hello world";
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_Test.java
index a2214841fb..7cd9c3f037 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Logging_Test.java
@@ -43,7 +43,7 @@ class RestClient_Logging_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public ABean bean(@Content ABean b) {
return b;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Marshalls_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Marshalls_Test.java
index 386e3a8041..63f36db633 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Marshalls_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Marshalls_Test.java
@@ -52,7 +52,7 @@ public class RestClient_Marshalls_Test extends TestBase {
public static Bean bean = Bean.create();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public Bean a01(@Content Bean b, @Header("Accept") String accept, @Header("Content-Type") String ct, @Header("X-Accept") String xaccept, @Header("X-Content-Type") String xct) {
assertEquals(nn(xaccept), nn(accept), "Accept doesn't match");
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Paths_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Paths_Test.java
index 90f5dbc1e1..b349922508 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Paths_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Paths_Test.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.*;
class RestClient_Paths_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet(path="/echo/*")
public String getEcho(org.apache.juneau.rest.RestRequest req) {
return req.toString();
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Query_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Query_Test.java
index 54b062c0dc..b3b51e9577 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Query_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Query_Test.java
@@ -40,7 +40,7 @@ import org.junit.jupiter.api.*;
class RestClient_Query_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public Reader query(org.apache.juneau.rest.RestRequest req) {
return reader(req.getQueryParams().asQueryString());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Body_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Body_Test.java
index 67c0bdacb9..84027dc716 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Body_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Body_Test.java
@@ -62,7 +62,7 @@ class RestClient_Response_Body_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestPost
public InputStream echo(InputStream is) {
return is;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Headers_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Headers_Test.java
index a68d2dabda..f2aa8a3060 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Headers_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Headers_Test.java
@@ -44,7 +44,7 @@ import org.junit.jupiter.api.*;
class RestClient_Response_Headers_Test extends TestBase {
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public String echo(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) {
var c = req.getHeaderParam("Check").orElse(null);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Test.java
index 0854df5ff1..c43d9fc556 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Response_Test.java
@@ -58,7 +58,7 @@ class RestClient_Response_Test extends TestBase {
private static final ZonedDateTime ZONEDDATETIME = ZonedDateTime.from(RFC_1123_DATE_TIME.parse("Sat, 29 Oct 1994 19:43:31 GMT")).truncatedTo(SECONDS);
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public ABean bean() {
return bean;
@@ -123,7 +123,7 @@ class RestClient_Response_Test extends TestBase {
//------------------------------------------------------------------------------------------------------------------
@Rest
- public static class C extends BasicRestObject {
+ public static class C extends BasicRestResource {
@RestGet(path="/")
public String getHeader(org.apache.juneau.rest.RestRequest req, org.apache.juneau.rest.RestResponse res) {
var n = req.getHeaderParam("Check").orElse(null);
@@ -197,7 +197,7 @@ class RestClient_Response_Test extends TestBase {
//------------------------------------------------------------------------------------------------------------------
@Rest
- public static class D extends BasicRestObject {
+ public static class D extends BasicRestResource {
@RestPost
public ABean bean(@Content ABean bean) {
return bean;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Test.java
index 9027050f3b..3ccec6d512 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/classic/RestClient_Test.java
@@ -63,7 +63,7 @@ class RestClient_Test extends TestBase {
private static ABean bean = ABean.get();
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet
public ABean bean() {
return bean;
@@ -290,7 +290,7 @@ class RestClient_Test extends TestBase {
//------------------------------------------------------------------------------------------------------------------
@Rest
- public static class D extends BasicRestObject {
+ public static class D extends BasicRestResource {
@RestGet
public String echo(@org.apache.juneau.http.annotation.Header("Authorization") String auth, org.apache.juneau.rest.RestResponse res) {
if (auth == null) {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_Builders_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_Builders_Test.java
index f34cd8e346..524aeabfa2 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_Builders_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_Builders_Test.java
@@ -43,22 +43,22 @@ import org.junit.jupiter.api.io.*;
*/
class BasicConvention_Builders_Test extends TestBase {
- // -------- BasicFaviconResource --------
+ // -------- FaviconMixin --------
@Test void favicon_noArgConstructorLoadsDefault() {
- var f = new BasicFaviconResource();
+ var f = new FaviconMixin();
assertNotNull(f);
}
@Test void favicon_classpathResolvesExistingResource() {
- var f = BasicFaviconResource.create()
+ var f = FaviconMixin.create()
.classpath("/juneau-favicon.ico")
.build();
assertNotNull(f);
}
@Test void favicon_classpathFallsBackOnMissingResource() {
- var f = BasicFaviconResource.create()
+ var f = FaviconMixin.create()
.classpath("/no-such-resource.ico")
.build();
assertNotNull(f, "Missing classpath path must fall back to default favicon");
@@ -66,7 +66,7 @@ class BasicConvention_Builders_Test extends TestBase {
@Test void favicon_bytesAndClasspathAreMutuallyExclusive() {
var bytes = new byte[]{1,2,3};
- var f = BasicFaviconResource.create()
+ var f = FaviconMixin.create()
.classpath("/anything.ico")
.bytes(bytes)
.build();
@@ -75,22 +75,22 @@ class BasicConvention_Builders_Test extends TestBase {
}
@Test void favicon_customCacheControl() {
- var f = BasicFaviconResource.create()
+ var f = FaviconMixin.create()
.bytes(new byte[]{1,2})
.cacheControl("no-store")
.build();
assertNotNull(f);
}
- // -------- BasicSeoResource --------
+ // -------- SeoMixin --------
@Test void seo_noArgConstructorYieldsDenyAll() {
- var s = new BasicSeoResource();
+ var s = new SeoMixin();
assertNotNull(s);
}
@Test void seo_robotsAllowAndDisallowMix() {
- var s = BasicSeoResource.create()
+ var s = SeoMixin.create()
.robotsAllow("Googlebot", "/")
.robotsDisallow("BadBot", "/private", "/admin")
.build();
@@ -98,7 +98,7 @@ class BasicConvention_Builders_Test extends TestBase {
}
@Test void seo_sitemapEntryWithFullMetadata() {
- var s = BasicSeoResource.create()
+ var s = SeoMixin.create()
.sitemapEntry("https://example.com/page",
ZonedDateTime.parse("2026-05-24T18:00:00Z"),
"weekly",
@@ -108,7 +108,7 @@ class BasicConvention_Builders_Test extends TestBase {
}
@Test void seo_sitemapEntryDirectInstance() {
- var e = new BasicSeoResource.SitemapEntry(
+ var e = new SeoMixin.SitemapEntry(
"https://x.example.com/<unsafe&\"chars'>",
ZonedDateTime.parse("2026-05-24T18:00:00+02:00"),
"daily",
@@ -132,45 +132,45 @@ class BasicConvention_Builders_Test extends TestBase {
@Test void seo_emptyPathArrayInRobotsRuleIsTolerated() {
// Internal RobotsRule's path-array handling — null/empty paths is just an empty rule.
- var s = BasicSeoResource.create().robotsAllow("MyBot").build();
+ var s = SeoMixin.create().robotsAllow("MyBot").build();
assertNotNull(s);
}
- // -------- BasicVersionResource --------
+ // -------- VersionMixin --------
@Test void version_noArgConstructorPopulatesDefaults() {
- var v = new BasicVersionResource();
+ var v = new VersionMixin();
assertNotNull(v.getInfoMap().get("javaVersion"), "no-arg ctor must surface javaVersion");
}
@Test void version_entryAcceptsNullValue() {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.entry("missing", null)
.build();
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("missing"));
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("missing"));
}
@Test void version_entriesMapSink() {
var values = new LinkedHashMap<String,String>();
values.put("a", "1");
values.put("b", null);
- var v = BasicVersionResource.create().entries(values).build();
+ var v = VersionMixin.create().entries(values).build();
assertEquals("1", v.getInfoMap().get("a"));
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("b"));
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("b"));
}
@Test void version_entriesNullMapIsTolerated() {
- var v = BasicVersionResource.create().entries(null).build();
+ var v = VersionMixin.create().entries(null).build();
assertNotNull(v);
}
@Test void version_fromManifestFallbackUnknownNameAndVersion() {
// URLClassLoader with no manifest available: name+version fall back to (unknown).
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromManifest(new URLClassLoader(new URL[0], null))
.build();
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("name"));
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("version"));
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("name"));
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("version"));
}
@Test void version_fromManifestObjectFullAttrs() {
@@ -181,7 +181,7 @@ class BasicConvention_Builders_Test extends TestBase {
attrs.putValue("Implementation-Version", "5.0.0");
attrs.putValue("Implementation-Vendor", "Co");
attrs.putValue("Build-Jdk", "21");
- var v = BasicVersionResource.create().fromManifest(m).build();
+ var v = VersionMixin.create().fromManifest(m).build();
assertEquals("obj-app", v.getInfoMap().get("name"));
assertEquals("5.0.0", v.getInfoMap().get("version"));
assertEquals("Co", v.getInfoMap().get("vendor"));
@@ -196,7 +196,7 @@ class BasicConvention_Builders_Test extends TestBase {
+ "git.build.time=2026-05-24T17:00:00Z\n";
Files.writeString(tempDir.resolve("git.properties"), props, StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(new URL[]{ tempDir.toUri().toURL() }, null)) {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromGitProperties(cl)
.build();
assertEquals("abcdef0123456789", v.getInfoMap().get("gitCommit"));
@@ -210,7 +210,7 @@ class BasicConvention_Builders_Test extends TestBase {
+ "git.branch=main\n";
Files.writeString(tempDir.resolve("git.properties"), props, StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(new URL[]{ tempDir.toUri().toURL() }, null)) {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromGitProperties(cl)
.build();
assertEquals("abcdef0", v.getInfoMap().get("gitCommit"),
@@ -220,7 +220,7 @@ class BasicConvention_Builders_Test extends TestBase {
@Test void version_fromGitPropertiesMissingFileIsSilent() throws Exception {
try (var cl = new URLClassLoader(new URL[0], null)) {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromGitProperties(cl)
.build();
assertNull(v.getInfoMap().get("gitCommit"),
@@ -236,17 +236,17 @@ class BasicConvention_Builders_Test extends TestBase {
"Manifest-Version: 1.0\nBuild-Jdk: 22\n\n",
StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(new URL[]{ tempDir.toUri().toURL() }, null)) {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromManifest(cl)
.build();
assertEquals("22", v.getInfoMap().get("javaVersion"));
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("name"),
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("name"),
"name unset → (unknown)");
}
}
@Test void version_fromJavaVersionPutsIfAbsent() {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.entry("javaVersion", "preset")
.fromJavaVersion()
.build();
@@ -262,7 +262,7 @@ class BasicConvention_Builders_Test extends TestBase {
attrs.putValue("Implementation-Title", "x");
attrs.putValue("Implementation-Version", "1");
attrs.putValue("Implementation-Vendor", "");
- var v = BasicVersionResource.create().fromManifest(m).build();
+ var v = VersionMixin.create().fromManifest(m).build();
assertNull(v.getInfoMap().get("vendor"), "empty string Implementation-Vendor must be skipped");
}
@@ -272,7 +272,7 @@ class BasicConvention_Builders_Test extends TestBase {
+ "git.build.time=\n";
Files.writeString(tempDir.resolve("git.properties"), props, StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(new URL[]{ tempDir.toUri().toURL() }, null)) {
- var v = BasicVersionResource.create().fromGitProperties(cl).build();
+ var v = VersionMixin.create().fromGitProperties(cl).build();
assertNull(v.getInfoMap().get("gitCommit"), "empty git.commit.id skipped");
assertNull(v.getInfoMap().get("gitBranch"), "empty git.branch skipped");
assertNull(v.getInfoMap().get("buildTime"), "empty git.build.time skipped");
@@ -288,9 +288,9 @@ class BasicConvention_Builders_Test extends TestBase {
throw new IOException("boom");
}
};
- var v = BasicVersionResource.create().fromManifest(brokenCl).build();
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("name"));
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("version"));
+ var v = VersionMixin.create().fromManifest(brokenCl).build();
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("name"));
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("version"));
}
@Test void version_fromGitPropertiesClassLoaderThrowsIOException() {
@@ -307,7 +307,7 @@ class BasicConvention_Builders_Test extends TestBase {
};
}
};
- var v = BasicVersionResource.create().fromGitProperties(brokenCl).build();
+ var v = VersionMixin.create().fromGitProperties(brokenCl).build();
assertNull(v.getInfoMap().get("gitCommit"), "broken git.properties read produces no entry");
}
@@ -321,8 +321,8 @@ class BasicConvention_Builders_Test extends TestBase {
"Manifest-Version: 1.0\nImplementation-Title: gone\n\n", StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(new URL[]{ tempDir.toUri().toURL() }, null)) {
Files.delete(manifest);
- var v = BasicVersionResource.create().fromManifest(cl).build();
- assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("name"));
+ var v = VersionMixin.create().fromManifest(cl).build();
+ assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("name"));
}
}
@@ -340,22 +340,22 @@ class BasicConvention_Builders_Test extends TestBase {
StandardCharsets.UTF_8);
try (var cl = new URLClassLoader(
new URL[]{ dirA.toUri().toURL(), dirB.toUri().toURL() }, null)) {
- var v = BasicVersionResource.create().fromManifest(cl).build();
+ var v = VersionMixin.create().fromManifest(cl).build();
assertEquals("titled", v.getInfoMap().get("name"),
"Locator must prefer Implementation-Title-bearing manifest");
}
}
- // -------- BasicWellKnownResource --------
+ // -------- WellKnownMixin --------
@Test void wellKnown_noArgConstructorYieldsNullBody() {
- var w = new BasicWellKnownResource();
+ var w = new WellKnownMixin();
assertNull(w.getSecurityTxtBody());
}
@Test void wellKnown_securityTxtBodyAccessor() {
var body = "Contact: x@example.com\nExpires: 2027-01-01T00:00:00Z\n";
- var w = BasicWellKnownResource.create().securityTxt(body).build();
+ var w = WellKnownMixin.create().securityTxt(body).build();
assertEquals(body, w.getSecurityTxtBody());
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_OpenApiHidden_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_OpenApiHidden_Test.java
index 3903409be2..6db045a2af 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_OpenApiHidden_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_OpenApiHidden_Test.java
@@ -31,7 +31,7 @@ import org.junit.jupiter.api.*;
*
* <p>
* The host extends vanilla {@link RestServlet} (not {@link BasicRestServlet}) and mounts the four
- * convention mixins plus {@link BasicOpenApiResource} (the OpenAPI generator). The generated spec
+ * convention mixins plus {@link OpenApiMixin} (the OpenAPI generator). The generated spec
* must list the host's own {@code /items} endpoint but NOT the convention paths.
*
* @since 9.5.0
@@ -40,11 +40,11 @@ class BasicConvention_OpenApiHidden_Test extends TestBase {
@Rest(
mixins={
- BasicFaviconResource.class,
- BasicSeoResource.class,
- BasicVersionResource.class,
- BasicWellKnownResource.class,
- BasicOpenApiResource.class
+ FaviconMixin.class,
+ SeoMixin.class,
+ VersionMixin.class,
+ WellKnownMixin.class,
+ OpenApiMixin.class
},
swaggerProvider=BasicSwaggerProvider.class
)
@@ -53,12 +53,12 @@ class BasicConvention_OpenApiHidden_Test extends TestBase {
@RestGet(path="/items") public String items() { return "items"; }
- @Bean public BasicVersionResource version() {
- return BasicVersionResource.create().entry("name", "convention-openapi-test").build();
+ @Bean public VersionMixin version() {
+ return VersionMixin.create().entry("name", "convention-openapi-test").build();
}
- @Bean public BasicWellKnownResource wellKnown() {
- return BasicWellKnownResource.create().securityTxt("Contact: x@example.com\n").build();
+ @Bean public WellKnownMixin wellKnown() {
+ return WellKnownMixin.create().securityTxt("Contact: x@example.com\n").build();
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_ParentChain_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_ParentChain_Test.java
index 05d1e01873..96ab42cdd7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_ParentChain_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicConvention_ParentChain_Test.java
@@ -49,33 +49,33 @@ import org.junit.jupiter.api.*;
class BasicConvention_ParentChain_Test extends TestBase {
@Rest(mixins={
- BasicFaviconResource.class,
- BasicSeoResource.class,
- BasicVersionResource.class,
- BasicWellKnownResource.class
+ FaviconMixin.class,
+ SeoMixin.class,
+ VersionMixin.class,
+ WellKnownMixin.class
})
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
- @Bean public BasicSeoResource seo() {
- return BasicSeoResource.create()
+ @Bean public SeoMixin seo() {
+ return SeoMixin.create()
.robotsAllow("*", "/")
.sitemapEntry("https://example.com/items")
.build();
}
- @Bean public BasicVersionResource version() {
- return BasicVersionResource.create()
+ @Bean public VersionMixin version() {
+ return VersionMixin.create()
.entry("name", "convention-pack")
.entry("version", "9.5.0")
.fromJavaVersion()
.build();
}
- @Bean public BasicWellKnownResource wellKnown() {
- return BasicWellKnownResource.create()
+ @Bean public WellKnownMixin wellKnown() {
+ return WellKnownMixin.create()
.securityTxt("Contact: security@example.com\nExpires: 2027-01-01T00:00:00Z\n")
.build();
}
@@ -88,10 +88,10 @@ class BasicConvention_ParentChain_Test extends TestBase {
var hostCtx = RestContext.getGlobalRegistry().get(A.class);
var ctxs = hostCtx.getMixinContexts();
- assertNotNull(ctxs.get(BasicFaviconResource.class), "Favicon mixin context registered");
- assertNotNull(ctxs.get(BasicSeoResource.class), "SEO mixin context registered");
- assertNotNull(ctxs.get(BasicVersionResource.class), "Version mixin context registered");
- assertNotNull(ctxs.get(BasicWellKnownResource.class), "Well-known mixin context registered");
+ assertNotNull(ctxs.get(FaviconMixin.class), "Favicon mixin context registered");
+ assertNotNull(ctxs.get(SeoMixin.class), "SEO mixin context registered");
+ assertNotNull(ctxs.get(VersionMixin.class), "Version mixin context registered");
+ assertNotNull(ctxs.get(WellKnownMixin.class), "Well-known mixin context registered");
assertEquals(4, ctxs.size(),
"Expected exactly four mixin contexts; got: " + ctxs.keySet());
}
@@ -118,7 +118,7 @@ class BasicConvention_ParentChain_Test extends TestBase {
@Test void a06_infoLegacyAliasNotMountedByDefault() throws Exception {
// FINISHED-101: /info is no longer a multi-path default. Migration to that secondary
- // alias is covered by BasicVersionResource_SvlPathOverride_Test#a02.
+ // alias is covered by VersionMixin_SvlPathOverride_Test#a02.
c.get("/info").run().assertStatus(404);
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicFaviconResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/FaviconMixin_AsMixin_Test.java
similarity index 84%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicFaviconResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/FaviconMixin_AsMixin_Test.java
index f99ee392fd..d6b8126aeb 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicFaviconResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/FaviconMixin_AsMixin_Test.java
@@ -24,26 +24,26 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicFaviconResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link FaviconMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
* Cases:
* <ul>
* <li>Default favicon (framework-shipped {@code /juneau-favicon.ico}) is served when no
- * {@code @Bean BasicFaviconResource} is registered on the host.
+ * {@code @Bean FaviconMixin} is registered on the host.
* <li>{@code Content-Type: image/x-icon} and 30-day {@code Cache-Control} headers flow through.
- * <li>Importer's {@code @Bean BasicFaviconResource} factory overrides the default bytes.
- * <li>{@link BasicFaviconResource.Builder#classpath(String) classpath(...)} loads icon bytes
+ * <li>Importer's {@code @Bean FaviconMixin} factory overrides the default bytes.
+ * <li>{@link FaviconMixin.Builder#classpath(String) classpath(...)} loads icon bytes
* from a classpath resource path.
* <li>The host's own endpoints are unaffected by the mixin.
* </ul>
*
* @since 9.5.0
*/
-class BasicFaviconResource_AsMixin_Test extends TestBase {
+class FaviconMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicFaviconResource.class)
+ @Rest(mixins=FaviconMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -77,12 +77,12 @@ class BasicFaviconResource_AsMixin_Test extends TestBase {
.assertContent().asString().isContains("items");
}
- /** Host with an importer-supplied {@code @Bean BasicFaviconResource} carrying custom bytes. */
- @Rest(mixins=BasicFaviconResource.class)
+ /** Host with an importer-supplied {@code @Bean FaviconMixin} carrying custom bytes. */
+ @Rest(mixins=FaviconMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicFaviconResource favicon() {
- return BasicFaviconResource.create()
+ @Bean public FaviconMixin favicon() {
+ return FaviconMixin.create()
.bytes(new byte[]{(byte)0xCA, (byte)0xFE, (byte)0xBA, (byte)0xBE})
.build();
}
@@ -104,13 +104,13 @@ class BasicFaviconResource_AsMixin_Test extends TestBase {
}
/** Host with an importer-supplied factory that loads bytes via classpath resource path. */
- @Rest(mixins=BasicFaviconResource.class)
+ @Rest(mixins=FaviconMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicFaviconResource favicon() {
+ @Bean public FaviconMixin favicon() {
// /juneau-favicon.ico is the framework's default-shipping classpath resource;
// loading it explicitly via classpath(...) verifies the classpath path works.
- return BasicFaviconResource.create()
+ return FaviconMixin.create()
.classpath("/juneau-favicon.ico")
.cacheControl("max-age=300, public")
.build();
@@ -129,7 +129,7 @@ class BasicFaviconResource_AsMixin_Test extends TestBase {
@Test void c02_classpathMissingFallsBackToDefault() throws Exception {
// A builder pointed at a missing classpath path falls back to the framework default.
- var fav = BasicFaviconResource.create()
+ var fav = FaviconMixin.create()
.classpath("/no-such-favicon.ico")
.build();
// Even with a missing classpath override, the default favicon resource provides bytes.
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicSeoResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/SeoMixin_AsMixin_Test.java
similarity index 90%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicSeoResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/SeoMixin_AsMixin_Test.java
index 2771706a02..0dbbe18709 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicSeoResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/SeoMixin_AsMixin_Test.java
@@ -24,7 +24,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicSeoResource} mounted as a mixin via {@code @Rest(mixins=...)} on a vanilla
+ * Validates {@link SeoMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a vanilla
* {@link RestServlet}.
*
* <p>
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.*;
* <ul>
* <li>Default {@code /robots.txt} returns deny-all when no override is registered.
* <li>Default {@code /sitemap.xml} returns an empty {@code <urlset>}.
- * <li>Importer's {@code @Bean BasicSeoResource} factory drives custom robots policy and sitemap
+ * <li>Importer's {@code @Bean SeoMixin} factory drives custom robots policy and sitemap
* entries.
* <li>Custom {@code robotsTxt(...)} body overrides any builder rules.
* <li>Content-Type pinning works for both endpoints.
@@ -40,10 +40,10 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicSeoResource_AsMixin_Test extends TestBase {
+class SeoMixin_AsMixin_Test extends TestBase {
/** Default-host mounting the mixin with no @Bean override. */
- @Rest(mixins=BasicSeoResource.class)
+ @Rest(mixins=SeoMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -76,11 +76,11 @@ class BasicSeoResource_AsMixin_Test extends TestBase {
}
/** Host with builder-driven robots policy via @Bean factory. */
- @Rest(mixins=BasicSeoResource.class)
+ @Rest(mixins=SeoMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicSeoResource seo() {
- return BasicSeoResource.create()
+ @Bean public SeoMixin seo() {
+ return SeoMixin.create()
.robotsAllow("*", "/")
.robotsDisallow("BadBot", "/private")
.sitemapEntry("https://example.com/")
@@ -106,11 +106,11 @@ class BasicSeoResource_AsMixin_Test extends TestBase {
}
/** Host with a custom robots body via robotsTxt(...). */
- @Rest(mixins=BasicSeoResource.class)
+ @Rest(mixins=SeoMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicSeoResource seo() {
- return BasicSeoResource.create()
+ @Bean public SeoMixin seo() {
+ return SeoMixin.create()
.robotsTxt("User-agent: *\nCrawl-delay: 10\nSitemap: https://example.com/sitemap.xml\n")
.build();
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_AsMixin_Test.java
similarity index 86%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_AsMixin_Test.java
index 51a786d344..0d1a4501d3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_AsMixin_Test.java
@@ -28,7 +28,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicVersionResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link VersionMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -36,7 +36,7 @@ import org.junit.jupiter.api.*;
* <ul>
* <li>{@code /version} returns the JSON map (single SVL-configurable default mount).
* <li>{@code Content-Type: application/json}.
- * <li>Importer's {@code @Bean BasicVersionResource} factory drives the entries map (manifest
+ * <li>Importer's {@code @Bean VersionMixin} factory drives the entries map (manifest
* read, programmatic entries, custom Manifest).
* <li>Missing manifest gracefully resolves to {@code (unknown)}.
* </ul>
@@ -45,13 +45,13 @@ import org.junit.jupiter.api.*;
* Per the FINISHED-101 multi-path collapse, the historical {@code /info} and {@code /about}
* mount aliases (formerly a triple default on a single op) are now reached via
* {@code -Djuneau.version.path=info} (or {@code about}); that behavior is covered by
- * {@code BasicVersionResource_SvlPathOverride_Test}.
+ * {@code VersionMixin_SvlPathOverride_Test}.
*
* @since 9.5.0
*/
-class BasicVersionResource_AsMixin_Test extends TestBase {
+class VersionMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -84,11 +84,11 @@ class BasicVersionResource_AsMixin_Test extends TestBase {
}
/** Host providing a programmatic version map via @Bean factory. */
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicVersionResource version() {
- return BasicVersionResource.create()
+ @Bean public VersionMixin version() {
+ return VersionMixin.create()
.entry("name", "my-app")
.entry("version", "1.2.3")
.entry("gitCommit", "abc123")
@@ -113,10 +113,10 @@ class BasicVersionResource_AsMixin_Test extends TestBase {
}
/** Host providing a synthetic Manifest via fromManifest(Manifest). */
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicVersionResource version() {
+ @Bean public VersionMixin version() {
var manifest = new Manifest();
var attrs = manifest.getMainAttributes();
attrs.putValue("Manifest-Version", "1.0");
@@ -124,7 +124,7 @@ class BasicVersionResource_AsMixin_Test extends TestBase {
attrs.putValue("Implementation-Version", "9.9.9");
attrs.putValue("Implementation-Vendor", "Acme");
attrs.putValue("Build-Jdk", "21.0.0");
- return BasicVersionResource.create().fromManifest(manifest).build();
+ return VersionMixin.create().fromManifest(manifest).build();
}
}
@@ -140,12 +140,12 @@ class BasicVersionResource_AsMixin_Test extends TestBase {
}
@Test void d01_missingManifestGracefulFallback() {
- var v = BasicVersionResource.create()
+ var v = VersionMixin.create()
.fromManifest(new java.net.URLClassLoader(new java.net.URL[0], null))
.build();
- Assertions.assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("name"),
+ Assertions.assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("name"),
"missing manifest must yield (unknown) name");
- Assertions.assertEquals(BasicVersionResource.UNKNOWN, v.getInfoMap().get("version"),
+ Assertions.assertEquals(VersionMixin.UNKNOWN, v.getInfoMap().get("version"),
"missing manifest must yield (unknown) version");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_JettyMicroservice_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_JettyMicroservice_Test.java
similarity index 91%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_JettyMicroservice_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_JettyMicroservice_Test.java
index 7721db0b06..bbcf501630 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_JettyMicroservice_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_JettyMicroservice_Test.java
@@ -34,13 +34,13 @@ import org.junit.jupiter.api.extension.*;
import jakarta.servlet.*;
/**
- * Real-Jetty deployment-parity assertion for {@link BasicVersionResource}.
+ * Real-Jetty deployment-parity assertion for {@link VersionMixin}.
*
* <p>
* Boots a {@link org.apache.juneau.microservice.Microservice Microservice} backed by
* {@link org.apache.juneau.microservice.jetty.JettyConfiguration JettyConfiguration} on an
* ephemeral port via {@link MicroserviceTestFixture}, mounts a vanilla {@link RestServlet} host
- * with the version mixin and a {@code @Bean BasicVersionResource} factory configuring known
+ * with the version mixin and a {@code @Bean VersionMixin} factory configuring known
* entries, and hits {@code /version}, {@code /info}, and {@code /about} over real HTTP.
*
* <p>
@@ -50,7 +50,7 @@ import jakarta.servlet.*;
* <li>JSON serialization through {@link org.apache.juneau.rest.RestResponse#getDirectWriter
* getDirectWriter("application/json")} on a vanilla {@link RestServlet} host (no JSON
* serializer wired up explicitly).
- * <li>Mixin-walk + bean-store override flow when {@code @Bean BasicVersionResource} is
+ * <li>Mixin-walk + bean-store override flow when {@code @Bean VersionMixin} is
* registered on the host: the mixin serves the host-supplied configuration end-to-end through
* the network stack.
* </ul>
@@ -58,13 +58,13 @@ import jakarta.servlet.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.JettyMicroserviceTest
-class BasicVersionResource_JettyMicroservice_Test extends TestBase {
+class VersionMixin_JettyMicroservice_Test extends TestBase {
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class Host extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicVersionResource version() {
- return BasicVersionResource.create()
+ @Bean public VersionMixin version() {
+ return VersionMixin.create()
.entry("name", "jetty-test")
.entry("version", "0.0.1")
.entry("gitCommit", "deadbeef")
@@ -112,7 +112,7 @@ class BasicVersionResource_JettyMicroservice_Test extends TestBase {
@Test void a02_infoLegacyAliasNotMountedByDefault() throws Exception {
// FINISHED-101: /info is no longer a multi-path default. Migration covered by
- // BasicVersionResource_SvlPathOverride_Test#a02.
+ // VersionMixin_SvlPathOverride_Test#a02.
var resp = get("/info");
assertTrue(resp.statusCode() == 404 || resp.statusCode() == 500,
"expected 404 or 500 (not mounted); got " + resp.statusCode() + ": " + resp.body());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_Springboot_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_Springboot_Test.java
similarity index 89%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_Springboot_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_Springboot_Test.java
index 6c8ba80b44..81238fe76f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_Springboot_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_Springboot_Test.java
@@ -36,20 +36,20 @@ import org.springframework.context.annotation.*;
import org.springframework.test.annotation.*;
/**
- * Real-Spring-Boot deployment-parity assertion for {@link BasicVersionResource}.
+ * Real-Spring-Boot deployment-parity assertion for {@link VersionMixin}.
*
* <p>
* Boots a full Spring Boot context with embedded Tomcat on a random port, registers a
* {@link BasicSpringRestServlet}-based host with the version mixin via
- * {@link ServletRegistrationBean}, supplies a Spring {@code @Bean BasicVersionResource}, and hits
+ * {@link ServletRegistrationBean}, supplies a Spring {@code @Bean VersionMixin}, and hits
* {@code /version}, {@code /info}, and {@code /about} over real HTTP.
*
* <p>
* Catches things {@code MockRest} and the
- * {@link BasicVersionResource_JettyMicroservice_Test Jetty parity test} cannot:
+ * {@link VersionMixin_JettyMicroservice_Test Jetty parity test} cannot:
* <ul>
* <li>Spring's bean store adapter ({@code SpringBeanStore}) resolving the host's
- * {@code @Bean BasicVersionResource} during the FINISHED-72 mixin walk through
+ * {@code @Bean VersionMixin} during the FINISHED-72 mixin walk through
* {@link org.springframework.context.ApplicationContext#getBean(Class)
* ApplicationContext.getBean(...)}.
* <li>End-to-end format-pinned JSON ({@link org.apache.juneau.rest.RestResponse#getDirectWriter
@@ -59,10 +59,10 @@ import org.springframework.test.annotation.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.SpringbootTest
-@SpringBootTest(classes = BasicVersionResource_Springboot_Test.TestApp.class,
+@SpringBootTest(classes = VersionMixin_Springboot_Test.TestApp.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class BasicVersionResource_Springboot_Test {
+class VersionMixin_Springboot_Test {
@SpringBootConfiguration
@EnableAutoConfiguration
@@ -79,8 +79,8 @@ class BasicVersionResource_Springboot_Test {
}
@Bean
- public BasicVersionResource versionResource() {
- return BasicVersionResource.create()
+ public VersionMixin versionResource() {
+ return VersionMixin.create()
.entry("name", "spring-test")
.entry("version", "0.0.2")
.entry("gitBranch", "release")
@@ -89,7 +89,7 @@ class BasicVersionResource_Springboot_Test {
}
}
- @Rest(mixins = BasicVersionResource.class)
+ @Rest(mixins = VersionMixin.class)
public static class Host extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -132,7 +132,7 @@ class BasicVersionResource_Springboot_Test {
@Test void a03_aboutLegacyAliasNotMountedByDefault() throws Exception {
// FINISHED-101: /about is no longer a multi-path default. Migration covered by
- // BasicVersionResource_SvlPathOverride_Test#a02.
+ // VersionMixin_SvlPathOverride_Test#a02.
var resp = get("/about");
assertTrue(resp.statusCode() == 404 || resp.statusCode() == 500,
"expected 404 or 500 (not mounted); got " + resp.statusCode() + ": " + resp.body());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_SvlPathOverride_Test.java
index b4844aff39..baa14a0e2f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_SvlPathOverride_Test.java
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code ${juneau.version.path:version}} SVL override on
- * {@link BasicVersionResource}.
+ * {@link VersionMixin}.
*
* <p>
* Per the FINISHED-101 multi-path collapse, the historical {@code /info} and {@code /about}
@@ -39,9 +39,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicVersionResource_SvlPathOverride_Test extends TestBase {
+class VersionMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -67,7 +67,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A02_InfoAliasMigration extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -93,7 +93,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A03_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -111,7 +111,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A04_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -129,7 +129,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A05_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -147,7 +147,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A06_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -165,7 +165,7 @@ class BasicVersionResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicVersionResource.class)
+ @Rest(mixins=VersionMixin.class)
public static class A07_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_ValueAdoption_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_ValueAdoption_Test.java
similarity index 86%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_ValueAdoption_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_ValueAdoption_Test.java
index dcb0f0c049..8329e82e6c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicVersionResource_ValueAdoption_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/VersionMixin_ValueAdoption_Test.java
@@ -23,7 +23,7 @@ import org.junit.jupiter.api.*;
/**
* TODO-92 acceptance tests for the {@code @Value}-driven {@code java.version} default on
- * {@link BasicVersionResource.Builder}.
+ * {@link VersionMixin.Builder}.
*
* <p>
* 3-test triad per migrated field per OQA #4 — system property set, unset (default = JVM-resolved),
@@ -34,7 +34,7 @@ import org.junit.jupiter.api.*;
* is set by the JVM itself; the assertion simply verifies that the JVM-supplied value is what flows
* through {@code @Value} resolution.
*/
-class BasicVersionResource_ValueAdoption_Test {
+class VersionMixin_ValueAdoption_Test {
private static final String SP = "java.version";
@@ -57,20 +57,20 @@ class BasicVersionResource_ValueAdoption_Test {
@Test
void a01_javaVersion_set() {
System.setProperty(SP, "todo92-set");
- var v = BasicVersionResource.create().fromJavaVersion().build().getInfoMap();
+ var v = VersionMixin.create().fromJavaVersion().build().getInfoMap();
assertEquals("todo92-set", v.get("javaVersion"));
}
@Test
void a02_javaVersion_unset() {
- var v = BasicVersionResource.create().fromJavaVersion().build().getInfoMap();
+ var v = VersionMixin.create().fromJavaVersion().build().getInfoMap();
assertEquals(saved, v.get("javaVersion"));
}
@Test
void a03_javaVersion_setGlobal() {
Settings.get().setGlobal(SP, "todo92-global");
- var v = BasicVersionResource.create().fromJavaVersion().build().getInfoMap();
+ var v = VersionMixin.create().fromJavaVersion().build().getInfoMap();
assertEquals("todo92-global", v.get("javaVersion"));
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicWellKnownResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/WellKnownMixin_AsMixin_Test.java
similarity index 85%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicWellKnownResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/convention/WellKnownMixin_AsMixin_Test.java
index 5f7fb1f597..493ed727c4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/convention/BasicWellKnownResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/convention/WellKnownMixin_AsMixin_Test.java
@@ -24,7 +24,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicWellKnownResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link WellKnownMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -32,15 +32,15 @@ import org.junit.jupiter.api.*;
* <ul>
* <li>{@code /.well-known/security.txt} returns {@code 404 Not Found} when no body is configured
* (per RFC 9116 default — no placeholder).
- * <li>Importer's {@code @Bean BasicWellKnownResource} factory drives the body content.
+ * <li>Importer's {@code @Bean WellKnownMixin} factory drives the body content.
* <li>{@code Content-Type: text/plain; charset=UTF-8} when a body is configured.
* </ul>
*
* @since 9.5.0
*/
-class BasicWellKnownResource_AsMixin_Test extends TestBase {
+class WellKnownMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicWellKnownResource.class)
+ @Rest(mixins=WellKnownMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -57,11 +57,11 @@ class BasicWellKnownResource_AsMixin_Test extends TestBase {
}
/** Host that configures a security.txt body via @Bean factory. */
- @Rest(mixins=BasicWellKnownResource.class)
+ @Rest(mixins=WellKnownMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicWellKnownResource wellKnown() {
- return BasicWellKnownResource.create()
+ @Bean public WellKnownMixin wellKnown() {
+ return WellKnownMixin.create()
.securityTxt("Contact: security@example.com\nExpires: 2027-01-01T00:00:00Z\n")
.build();
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_JettyMicroservice_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_JettyMicroservice_Test.java
index 075156bb78..8125ac1725 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_JettyMicroservice_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_JettyMicroservice_Test.java
@@ -38,8 +38,8 @@ import jakarta.servlet.*;
* {@link org.apache.juneau.microservice.jetty.JettyConfiguration JettyConfiguration} on an
* ephemeral port via {@link MicroserviceTestFixture}, mounts a {@link BasicRestServlet} host that
* inherits the four-mixin pack
- * ({@link BasicSwaggerUiResource} + {@link BasicRedocResource} — transitively pulling in
- * {@link BasicSwaggerResource} + {@link BasicOpenApiResource}), and then hits the six canonical
+ * ({@link SwaggerUiMixin} + {@link RedocMixin} — transitively pulling in
+ * {@link SwaggerMixin} + {@link OpenApiMixin}), and then hits the six canonical
* api-docs URLs over real HTTP.
*
* <p>
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_ParentChain_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_ParentChain_Test.java
index c79e9ab109..c4f9a8e2e0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_ParentChain_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_ParentChain_Test.java
@@ -21,7 +21,9 @@ import static org.junit.jupiter.api.Assertions.*;
import org.apache.juneau.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.convention.*;
import org.apache.juneau.rest.mock.classic.*;
+import org.apache.juneau.rest.ops.*;
import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
@@ -32,27 +34,27 @@ import org.junit.jupiter.api.*;
* <p>
* Setup:
* <ul>
- * <li>{@code Parent} declares {@code @Rest(mixins=BasicSwaggerUiResource.class)}.
- * <li>{@code Child} extends {@code Parent} and declares {@code @Rest(mixins=BasicRedocResource.class)}.
+ * <li>{@code Parent} declares {@code @Rest(mixins=SwaggerUiMixin.class)}.
+ * <li>{@code Child} extends {@code Parent} and declares {@code @Rest(mixins=RedocMixin.class)}.
* </ul>
*
* <p>
* Acceptance:
* <ul>
* <li>{@code Child}'s {@code mixinContexts} map contains all four mixin classes
- * ({@code BasicSwaggerUiResource}, {@code BasicSwaggerResource} via transitive,
- * {@code BasicRedocResource}, {@code BasicOpenApiResource} via transitive).
+ * ({@code SwaggerUiMixin}, {@code SwaggerMixin} via transitive,
+ * {@code RedocMixin}, {@code OpenApiMixin} via transitive).
* <li>All four URL paths resolve correctly.
* </ul>
*/
class BasicApiDocs_ParentChain_Test extends TestBase {
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class Parent extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class Child extends Parent {
private static final long serialVersionUID = 1L;
}
@@ -64,13 +66,18 @@ class BasicApiDocs_ParentChain_Test extends TestBase {
var hostCtx = RestContext.getGlobalRegistry().get(Child.class);
var contexts = hostCtx.getMixinContexts();
- assertNotNull(contexts.get(BasicSwaggerUiResource.class), "Parent's mixin must propagate to child");
- assertNotNull(contexts.get(BasicSwaggerResource.class), "Parent's transitive mixin must propagate to child");
- assertNotNull(contexts.get(BasicRedocResource.class), "Child's mixin must be present");
- assertNotNull(contexts.get(BasicOpenApiResource.class), "Child's transitive mixin must be present");
+ assertNotNull(contexts.get(SwaggerUiMixin.class), "Parent's mixin must propagate to child");
+ assertNotNull(contexts.get(SwaggerMixin.class), "Parent's transitive mixin must propagate to child");
+ assertNotNull(contexts.get(RedocMixin.class), "Child's mixin must be present");
+ assertNotNull(contexts.get(OpenApiMixin.class), "Child's transitive mixin must be present");
+ // Residual op-mixins contributed by the BasicRestServlet base of the parent chain.
+ assertNotNull(contexts.get(ErrorMixin.class));
+ assertNotNull(contexts.get(HtdocMixin.class));
+ assertNotNull(contexts.get(StatsMixin.class));
+ assertNotNull(contexts.get(FaviconMixin.class));
- assertEquals(4, contexts.size(),
- "Expected exactly four mixin contexts; got: " + contexts.keySet());
+ assertEquals(8, contexts.size(),
+ "Expected exactly eight mixin contexts; got: " + contexts.keySet());
}
@Test void a02_apiFromParentChain() throws Exception {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_Springboot_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_Springboot_Test.java
index 0e13ab00e8..e3c2deb59c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_Springboot_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_Springboot_Test.java
@@ -39,8 +39,8 @@ import org.springframework.test.annotation.*;
* <p>
* Boots a full Spring Boot context with embedded Tomcat on a random port, registers a
* {@link BasicSpringRestServlet}-based host wired up with the four-mixin pack
- * ({@link BasicSwaggerUiResource} + {@link BasicRedocResource} — transitively pulling in
- * {@link BasicSwaggerResource} + {@link BasicOpenApiResource}) via {@link ServletRegistrationBean},
+ * ({@link SwaggerUiMixin} + {@link RedocMixin} — transitively pulling in
+ * {@link SwaggerMixin} + {@link OpenApiMixin}) via {@link ServletRegistrationBean},
* and hits the six canonical api-docs URLs over real HTTP via {@link HttpClient}.
*
* <p>
@@ -109,7 +109,7 @@ class BasicApiDocs_Springboot_Test {
* Inherited}, so this child annotation aggregates with the parent's via the mixin walk
* (parent-first, child-appended; {@code LinkedHashSet} dedupes by class identity).
*/
- @Rest(mixins = {BasicSwaggerUiResource.class, BasicRedocResource.class})
+ @Rest(mixins = {SwaggerUiMixin.class, RedocMixin.class})
public static class Host extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_TransitiveDedupe_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_TransitiveDedupe_Test.java
index d0438b80d3..3810488f76 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_TransitiveDedupe_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicApiDocs_TransitiveDedupe_Test.java
@@ -21,7 +21,9 @@ import static org.junit.jupiter.api.Assertions.*;
import org.apache.juneau.*;
import org.apache.juneau.rest.*;
import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.convention.*;
import org.apache.juneau.rest.mock.classic.*;
+import org.apache.juneau.rest.ops.*;
import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
@@ -30,40 +32,49 @@ import org.junit.jupiter.api.*;
* together.
*
* <p>
- * {@code @Rest(mixins={BasicSwaggerUiResource.class, BasicRedocResource.class})} should pull in
- * {@code BasicSwaggerResource} (via {@code BasicSwaggerUiResource}) and
- * {@code BasicOpenApiResource} (via {@code BasicRedocResource}) exactly once each — not twice,
+ * {@code @Rest(mixins={SwaggerUiMixin.class, RedocMixin.class})} should pull in
+ * {@code SwaggerMixin} (via {@code SwaggerUiMixin}) and
+ * {@code OpenApiMixin} (via {@code RedocMixin}) exactly once each — not twice,
* even though the user could equivalently have listed all four mixins explicitly.
*
* <p>
* Acceptance:
* <ul>
- * <li>All four mixin classes are present in the host's {@code mixinContexts} map.
- * <li>Each mixin appears exactly once (no duplicates).
- * <li>All six URL paths (across the four mixins) resolve correctly.
+ * <li>The four api-docs mixin classes are present in the host's {@code mixinContexts} map, alongside the
+ * four residual op-mixins ({@code ErrorMixin}, {@code HtdocMixin}, {@code StatsMixin},
+ * {@code FaviconMixin}) contributed by {@code BasicRestServlet}.
+ * <li>Each mixin appears exactly once (no duplicates) — eight in total.
+ * <li>All six api-docs URL paths resolve correctly.
* </ul>
*/
class BasicApiDocs_TransitiveDedupe_Test extends TestBase {
- @Rest(mixins={BasicSwaggerUiResource.class, BasicRedocResource.class})
+ @Rest(mixins={SwaggerUiMixin.class, RedocMixin.class})
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
private static final MockRestClient c = MockRestClient.buildLax(A.class);
- @Test void a01_allFourMixinContextsPresent() throws Exception {
+ @Test void a01_allMixinContextsPresent() throws Exception {
MockRestClient.buildLax(A.class);
var hostCtx = RestContext.getGlobalRegistry().get(A.class);
var contexts = hostCtx.getMixinContexts();
- assertNotNull(contexts.get(BasicSwaggerUiResource.class));
- assertNotNull(contexts.get(BasicSwaggerResource.class));
- assertNotNull(contexts.get(BasicRedocResource.class));
- assertNotNull(contexts.get(BasicOpenApiResource.class));
+ // api-docs pack — deduped from A's explicit SwaggerUiMixin/RedocMixin + BasicRestServlet's own list
+ // plus the transitive SwaggerMixin/OpenApiMixin pulls (each present exactly once).
+ assertNotNull(contexts.get(SwaggerUiMixin.class));
+ assertNotNull(contexts.get(SwaggerMixin.class));
+ assertNotNull(contexts.get(RedocMixin.class));
+ assertNotNull(contexts.get(OpenApiMixin.class));
+ // Residual op-mixins contributed by BasicRestServlet.
+ assertNotNull(contexts.get(ErrorMixin.class));
+ assertNotNull(contexts.get(HtdocMixin.class));
+ assertNotNull(contexts.get(StatsMixin.class));
+ assertNotNull(contexts.get(FaviconMixin.class));
- assertEquals(4, contexts.size(),
- "Expected exactly four mixin contexts (no duplicates); got: " + contexts.keySet());
+ assertEquals(8, contexts.size(),
+ "Expected exactly eight mixin contexts (no duplicates); got: " + contexts.keySet());
}
@Test void a02_apiPathReachable() throws Exception {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_AsMixin_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_AsMixin_Test.java
index 0098b39e34..f7e92158d0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_AsMixin_Test.java
@@ -23,7 +23,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicOpenApiResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link OpenApiMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -35,9 +35,9 @@ import org.junit.jupiter.api.*;
* <li>The host's own endpoints are unaffected.
* </ul>
*/
-class BasicOpenApiResource_AsMixin_Test extends TestBase {
+class OpenApiMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_SvlPathOverride_Test.java
index 71e061ffc7..b63abd5a05 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicOpenApiResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/OpenApiMixin_SvlPathOverride_Test.java
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code ${juneau.openapi.path:openapi}} SVL override on
- * {@link BasicOpenApiResource}.
+ * {@link OpenApiMixin}.
*
* <p>
* The same variable is reused across all three op-paths on this mixin
@@ -39,9 +39,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
+class OpenApiMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -77,7 +77,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A02_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -95,7 +95,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A03_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -113,7 +113,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A04_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -131,7 +131,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A05_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -149,7 +149,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A06_WildcardSuffix extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -167,7 +167,7 @@ class BasicOpenApiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicOpenApiResource.class)
+ @Rest(mixins=OpenApiMixin.class)
public static class A07_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_AsMixin_Test.java
similarity index 85%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_AsMixin_Test.java
index 57285b4300..504963d9fa 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_AsMixin_Test.java
@@ -26,12 +26,12 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicRedocResource} mounted as a mixin.
+ * Validates {@link RedocMixin} mounted as a mixin.
*
* <p>
* Acceptance:
* <ul>
- * <li>Transitive resolution brings in {@link BasicOpenApiResource}: {@code /openapi}, {@code /openapi.json},
+ * <li>Transitive resolution brings in {@link OpenApiMixin}: {@code /openapi}, {@code /openapi.json},
* and {@code /openapi.yaml} are all mounted alongside {@code /redoc}.
* <li>{@code GET /redoc} with no {@code Accept} header renders HTML (via {@code defaultAccept}).
* <li>{@code GET /redoc} with {@code Accept: application/json} returns the OpenAPI spec as JSON
@@ -39,9 +39,9 @@ import org.junit.jupiter.api.*;
* <li>Both endpoints are backed by separate sub-{@code RestContext}s.
* </ul>
*/
-class BasicRedocResource_AsMixin_Test extends TestBase {
+class RedocMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -90,7 +90,7 @@ class BasicRedocResource_AsMixin_Test extends TestBase {
MockRestClient.buildLax(A.class);
var hostCtx = RestContext.getGlobalRegistry().get(A.class);
var contexts = hostCtx.getMixinContexts();
- assertNotNull(contexts.get(BasicRedocResource.class), "BasicRedocResource sub-context must be present");
- assertNotNull(contexts.get(BasicOpenApiResource.class), "BasicOpenApiResource sub-context must be transitively present");
+ assertNotNull(contexts.get(RedocMixin.class), "RedocMixin sub-context must be present");
+ assertNotNull(contexts.get(OpenApiMixin.class), "OpenApiMixin sub-context must be transitively present");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_SvlPathOverride_Test.java
index 3ecd29a9f4..27829bfe76 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicRedocResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/RedocMixin_SvlPathOverride_Test.java
@@ -23,7 +23,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates the {@code ${juneau.redoc.path:redoc}} SVL override on {@link BasicRedocResource}.
+ * Validates the {@code ${juneau.redoc.path:redoc}} SVL override on {@link RedocMixin}.
*
* <p>
* Uses a fresh inner-class resource because {@link MockRestClient} caches {@link RestContext} per
@@ -31,9 +31,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicRedocResource_SvlPathOverride_Test extends TestBase {
+class RedocMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -61,7 +61,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A02_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -79,7 +79,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A03_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -97,7 +97,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A04_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -115,7 +115,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A05_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -133,7 +133,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A06_WildcardSuffix extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -151,7 +151,7 @@ class BasicRedocResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRedocResource.class)
+ @Rest(mixins=RedocMixin.class)
public static class A07_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_AsMixin_Test.java
similarity index 92%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_AsMixin_Test.java
index 20490d4258..9101a36b5a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_AsMixin_Test.java
@@ -24,7 +24,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicSwaggerResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link SwaggerMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -37,9 +37,9 @@ import org.junit.jupiter.api.*;
* <li>The host's own endpoints are unaffected.
* </ul>
*/
-class BasicSwaggerResource_AsMixin_Test extends TestBase {
+class SwaggerMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_Standalone_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_Standalone_Test.java
similarity index 83%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_Standalone_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_Standalone_Test.java
index c10f02140c..28ac1d89d0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_Standalone_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_Standalone_Test.java
@@ -25,20 +25,20 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicSwaggerResource} composed onto a vanilla {@link RestServlet} — i.e. used
+ * Validates {@link SwaggerMixin} composed onto a vanilla {@link RestServlet} — i.e. used
* outside of the {@code BasicRestServlet} chain.
*
* <p>
* The mixin's {@code @RestOp} methods are pure POJOs that inherit serializers/parsers from the
* host's {@code RestContext} via the FINISHED-81 sub-context model. This test demonstrates that a
- * minimal host (vanilla {@link RestObject} + {@link BasicUniversalConfig}) is sufficient to mount
+ * minimal host (vanilla {@link RestResource} + {@link BasicUniversalConfig}) is sufficient to mount
* the {@code /api} endpoint without dragging in the rest of the {@code BasicRestOperations}
* surface.
*/
-class BasicSwaggerResource_Standalone_Test extends TestBase {
+class SwaggerMixin_Standalone_Test extends TestBase {
- @Rest(mixins=BasicSwaggerResource.class)
- public static class A extends RestObject implements BasicUniversalConfig {}
+ @Rest(mixins=SwaggerMixin.class)
+ public static class A extends RestResource implements BasicUniversalConfig {}
private static final MockRestClient c = MockRestClient.buildLax(A.class);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_SvlPathOverride_Test.java
index 94658e0cc8..4059dcfb76 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerMixin_SvlPathOverride_Test.java
@@ -23,7 +23,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates the {@code ${juneau.swagger.path:api}} SVL override on {@link BasicSwaggerResource}.
+ * Validates the {@code ${juneau.swagger.path:api}} SVL override on {@link SwaggerMixin}.
*
* <p>
* Uses a fresh inner-class resource because {@link MockRestClient} caches {@link RestContext} per
@@ -33,9 +33,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
+class SwaggerMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -65,7 +65,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A02_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -83,7 +83,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A03_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -101,7 +101,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A04_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -119,7 +119,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A05_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -137,7 +137,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A06_WildcardSuffix extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -155,7 +155,7 @@ class BasicSwaggerResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerResource.class)
+ @Rest(mixins=SwaggerMixin.class)
public static class A07_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_AsMixin_Test.java
similarity index 84%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_AsMixin_Test.java
index 88ce6ceea8..3bc8f42260 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_AsMixin_Test.java
@@ -27,12 +27,12 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicSwaggerUiResource} mounted as a mixin.
+ * Validates {@link SwaggerUiMixin} mounted as a mixin.
*
* <p>
* Acceptance:
* <ul>
- * <li>Transitive resolution brings in {@link BasicSwaggerResource}: {@code /api} is mounted alongside
+ * <li>Transitive resolution brings in {@link SwaggerMixin}: {@code /api} is mounted alongside
* {@code /swagger}.
* <li>{@code GET /swagger} with no {@code Accept} header renders HTML (via the {@code defaultAccept})
* — this is the no-Accept-defaults-to-HTML behavior unique to UI mixins.
@@ -42,9 +42,9 @@ import org.junit.jupiter.api.*;
* <li>Both endpoints are backed by separate sub-{@code RestContext}s per FINISHED-81.
* </ul>
*/
-class BasicSwaggerUiResource_AsMixin_Test extends TestBase {
+class SwaggerUiMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -79,7 +79,7 @@ class BasicSwaggerUiResource_AsMixin_Test extends TestBase {
MockRestClient.buildLax(A.class);
var hostCtx = RestContext.getGlobalRegistry().get(A.class);
var contexts = hostCtx.getMixinContexts();
- assertNotNull(contexts.get(BasicSwaggerUiResource.class), "BasicSwaggerUiResource sub-context must be present");
- assertNotNull(contexts.get(BasicSwaggerResource.class), "BasicSwaggerResource sub-context must be transitively present");
+ assertNotNull(contexts.get(SwaggerUiMixin.class), "SwaggerUiMixin sub-context must be present");
+ assertNotNull(contexts.get(SwaggerMixin.class), "SwaggerMixin sub-context must be transitively present");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_SvlPathOverride_Test.java
index be0cd7fd06..740842a3df 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/docs/BasicSwaggerUiResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/docs/SwaggerUiMixin_SvlPathOverride_Test.java
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code ${juneau.swaggerui.path:swagger}} SVL override on
- * {@link BasicSwaggerUiResource}.
+ * {@link SwaggerUiMixin}.
*
* <p>
* Uses a fresh inner-class resource because {@link MockRestClient} caches {@link RestContext} per
@@ -32,9 +32,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
+class SwaggerUiMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -62,7 +62,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A02_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -80,7 +80,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A03_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -98,7 +98,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A04_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -116,7 +116,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A05_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -134,7 +134,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A06_WildcardSuffix extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -152,7 +152,7 @@ class BasicSwaggerUiResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicSwaggerUiResource.class)
+ @Rest(mixins=SwaggerUiMixin.class)
public static class A07_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthMixin_Test.java
similarity index 95%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthMixin_Test.java
index 3418163d72..3857d6f017 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthMixin_Test.java
@@ -29,9 +29,9 @@ import org.apache.juneau.rest.mock.classic.*;
import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
-class BasicHealthResource_AsMixin_Test extends TestBase {
+class HealthMixin_Test extends TestBase {
- @Rest(mixins={BasicHealthResource.class})
+ @Rest(mixins={HealthMixin.class})
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthServlet_Test.java
similarity index 94%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthServlet_Test.java
index 2e0063f82e..48c0b126f7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/health/BasicHealthResource_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/health/HealthServlet_Test.java
@@ -25,10 +25,10 @@ import org.apache.juneau.rest.annotation.*;
import org.apache.juneau.rest.mock.classic.*;
import org.junit.jupiter.api.*;
-class BasicHealthResource_Test extends TestBase {
+class HealthServlet_Test extends TestBase {
@Rest
- public static class A extends BasicHealthResource {
+ public static class A extends HealthServlet {
@Override
protected Map<String,HealthIndicator> indicators() {
return Map.of(
@@ -39,7 +39,7 @@ class BasicHealthResource_Test extends TestBase {
}
@Rest
- public static class B extends BasicHealthResource {
+ public static class B extends HealthServlet {
@Override
protected Map<String,HealthIndicator> indicators() {
return Map.of(
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiSchemaReuse_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiSchemaReuse_Test.java
index 872f431bd3..78c92ff5c7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiSchemaReuse_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiSchemaReuse_Test.java
@@ -63,7 +63,7 @@ class OpenApiSchemaReuse_Test extends TestBase {
}
@Rest
- public static class A extends BasicRestObject {
+ public static class A extends BasicRestResource {
@RestGet(path="/pet") public Pet getPet() { return new Pet(); }
@RestPost(path="/pet") public Pet createPet(@Content Pet pet) { return pet; }
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiYamlRoundTrip_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiYamlRoundTrip_Test.java
index fe2097a955..d356da0057 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiYamlRoundTrip_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/openapi/OpenApiYamlRoundTrip_Test.java
@@ -89,7 +89,7 @@ class OpenApiYamlRoundTrip_Test extends TestBase {
// Inherits the FULL BasicRestServlet api-docs mixin surface — six api-docs URLs, full schema
// set, the works. Earlier this resource shipped with noInherit={"mixins"} + mixins={
- // BasicOpenApiResource} because round-tripping the full doc through the YAML parser threw
+ // OpenApiMixin} because round-tripping the full doc through the YAML parser threw
// IOException: Buffer underflow; that latent ParserReader limitation was fixed by widening the
// reader's no-mark unread-lookback window (see ParserReader.UNMARKED_LOOKBACK_CHARS), so c01
// now asserts against the FULL mixin-pack mount surface.
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AsMixin_Test.java
similarity index 89%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AsMixin_Test.java
index c1a360b0a2..15382f0ced 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AsMixin_Test.java
@@ -30,7 +30,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicAdminResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link AdminMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -49,13 +49,13 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicAdminResource_AsMixin_Test extends TestBase {
+class AdminMixin_AsMixin_Test extends TestBase {
// -----------------------------------------------------------------------------------------
// Default-deny posture (no host-supplied @Bean RestGuardList).
// -----------------------------------------------------------------------------------------
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -88,7 +88,7 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
// -----------------------------------------------------------------------------------------
/** Allow-all guard chain — replaces the mixin's annotation-derived deny-all. */
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -97,8 +97,8 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
return RestGuardList.create(bs).build();
}
- @Bean public BasicAdminResource admin() {
- return BasicAdminResource.create()
+ @Bean public AdminMixin admin() {
+ return AdminMixin.create()
.cacheFlush("primary", FLUSH_PRIMARY)
.cacheFlush("secondary", FLUSH_SECONDARY)
.threadNamePrefixExclude() // disable filtering to make /admin/threads deterministic
@@ -188,7 +188,7 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
// Allow-all guard list + a registered RateLimitGuard bean.
// -----------------------------------------------------------------------------------------
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -221,14 +221,14 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
@Test void d01_builderRejectsBlankCacheFlushName() {
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicAdminResource.create().cacheFlush("", () -> {}));
+ () -> AdminMixin.create().cacheFlush("", () -> {}));
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicAdminResource.create().cacheFlush(null, () -> {}));
+ () -> AdminMixin.create().cacheFlush(null, () -> {}));
}
@Test void d02_builderRejectsNullHook() {
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicAdminResource.create().cacheFlush("foo", null));
+ () -> AdminMixin.create().cacheFlush("foo", null));
}
@Test void d03_cacheFlushAllRoundTrips() {
@@ -237,26 +237,26 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
var r2 = (Runnable) () -> {};
hooks.put("a", r1);
hooks.put("b", r2);
- var admin = BasicAdminResource.create().cacheFlushAll(hooks).build();
+ var admin = AdminMixin.create().cacheFlushAll(hooks).build();
Assertions.assertEquals(2, admin.getCacheFlushHooks().size());
Assertions.assertSame(r1, admin.getCacheFlushHooks().get("a"));
Assertions.assertSame(r2, admin.getCacheFlushHooks().get("b"));
}
@Test void d04_threadNameExcludeReplaceList() {
- var admin = BasicAdminResource.create().threadNamePrefixExclude("foo-", "bar-").build();
+ var admin = AdminMixin.create().threadNamePrefixExclude("foo-", "bar-").build();
Assertions.assertEquals(List.of("foo-", "bar-"), admin.getThreadNamePrefixExclude());
}
@Test void d05_defaultExcludeListContainsKnownNoise() {
- Assertions.assertTrue(BasicAdminResource.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE.contains("Reference Handler"));
- Assertions.assertTrue(BasicAdminResource.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE.contains("jetty-"));
+ Assertions.assertTrue(AdminMixin.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE.contains("Reference Handler"));
+ Assertions.assertTrue(AdminMixin.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE.contains("jetty-"));
}
@Test void d06_noArgConstructorMatchesEmptyHooks() {
- var r = new BasicAdminResource();
+ var r = new AdminMixin();
Assertions.assertTrue(r.getCacheFlushHooks().isEmpty());
- Assertions.assertEquals(BasicAdminResource.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE,
+ Assertions.assertEquals(AdminMixin.DEFAULT_THREAD_NAME_PREFIX_EXCLUDE,
r.getThreadNamePrefixExclude());
}
@@ -267,18 +267,18 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
}
@Test void d08_cacheFlushAllNullIsNoOp() {
- var admin = BasicAdminResource.create().cacheFlushAll(null).build();
+ var admin = AdminMixin.create().cacheFlushAll(null).build();
Assertions.assertTrue(admin.getCacheFlushHooks().isEmpty());
}
@Test void d09_threadNamePrefixExcludeNullClearsList() {
- var admin = BasicAdminResource.create().threadNamePrefixExclude((String[]) null).build();
+ var admin = AdminMixin.create().threadNamePrefixExclude((String[]) null).build();
Assertions.assertTrue(admin.getThreadNamePrefixExclude().isEmpty(),
"null varargs should clear the list");
}
@Test void d10_threadNamePrefixExcludeFiltersNullAndEmpty() {
- var admin = BasicAdminResource.create().threadNamePrefixExclude("good-", null, "", "also-").build();
+ var admin = AdminMixin.create().threadNamePrefixExclude("good-", null, "", "also-").build();
Assertions.assertEquals(List.of("good-", "also-"), admin.getThreadNamePrefixExclude());
}
@@ -287,15 +287,15 @@ class BasicAdminResource_AsMixin_Test extends TestBase {
// isExcludedThread when the configured filter list catches a real thread).
// -----------------------------------------------------------------------------------------
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class F extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
// Prefix that will match the JUnit launcher / test thread on every supported JVM.
- @Bean public BasicAdminResource admin() {
- return BasicAdminResource.create()
+ @Bean public AdminMixin admin() {
+ return AdminMixin.create()
.threadNamePrefixExclude("ForkJoinPool", "main", "junit-")
.build();
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AuthIntegration_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AuthIntegration_Test.java
similarity index 94%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AuthIntegration_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AuthIntegration_Test.java
index ebf7415180..5f498c2256 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_AuthIntegration_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_AuthIntegration_Test.java
@@ -29,20 +29,20 @@ import org.junit.jupiter.api.*;
/**
* End-to-end integration smoke test for FINISHED-77's
- * {@link BasicAdminResource}-with-DenyAllGuard-default ↔ TODO-69's {@link BearerTokenGuard}
+ * {@link AdminMixin}-with-DenyAllGuard-default ↔ TODO-69's {@link BearerTokenGuard}
* cross-cut. Confirms the migration claim from FINISHED-77's Related-work cross-link: swapping
* {@link org.apache.juneau.rest.guard.DenyAllGuard DenyAllGuard} for an AuthN guard is a
* zero-mixin-source-change drop-in.
*
* <p>
- * Each case sits on a host servlet that mounts {@link BasicAdminResource} as a mixin and supplies
+ * Each case sits on a host servlet that mounts {@link AdminMixin} as a mixin and supplies
* its own {@code @Bean RestGuardList} containing a {@link BearerTokenGuard} backed by a
* fixed-token validator. The framework's {@code @Bean RestGuardList} override REPLACES the
* annotation-derived deny-all on the mixin, so the admin paths gate on the bearer token instead.
*
* @since 9.5.0
*/
-class BasicAdminResource_AuthIntegration_Test extends TestBase {
+class AdminMixin_AuthIntegration_Test extends TestBase {
private static final Principal ADMIN = () -> "admin";
@@ -53,7 +53,7 @@ class BasicAdminResource_AuthIntegration_Test extends TestBase {
throw new AuthenticationException("Invalid token");
};
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_RateLimitSnapshot_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_RateLimitSnapshot_Test.java
similarity index 95%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_RateLimitSnapshot_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_RateLimitSnapshot_Test.java
index a3038b17cf..d6fcd802d7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_RateLimitSnapshot_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_RateLimitSnapshot_Test.java
@@ -30,24 +30,24 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates that {@link BasicAdminResource#getRateLimit} on the {@code /admin/ratelimit} endpoint
+ * Validates that {@link AdminMixin#getRateLimit} on the {@code /admin/ratelimit} endpoint
* surfaces both static {@code config} and live {@code snapshot} bucket state when a
* {@link RateLimitGuard} is registered.
*
* <p>
- * Builds on {@code BasicAdminResource_AsMixin_Test}'s {@code c01_rateLimitListsRegisteredGuard}
+ * Builds on {@code AdminMixin_AsMixin_Test}'s {@code c01_rateLimitListsRegisteredGuard}
* pattern; the snapshot coverage is the v1 follow-up that closes the {@code "buckets": []}
* placeholder noted in the FINISHED-77 archive.
*
* @since 9.5.0
*/
-class BasicAdminResource_RateLimitSnapshot_Test extends TestBase {
+class AdminMixin_RateLimitSnapshot_Test extends TestBase {
// -----------------------------------------------------------------------------------------
// Single RateLimitGuard bean — snapshot reports per-key bucket state after activity.
//
// Stash the guard in a static field so the instance the GuardList enforces on /items is the
- // same instance BasicAdminResource resolves from the bean store. The @Bean RateLimitGuard
+ // same instance AdminMixin resolves from the bean store. The @Bean RateLimitGuard
// factory method below is invoked once by the bean store; both the guard chain (via
// bs.getBean(...)) and the admin endpoint pick up that single cached instance.
// -----------------------------------------------------------------------------------------
@@ -59,7 +59,7 @@ class BasicAdminResource_RateLimitSnapshot_Test extends TestBase {
.exemptPaths("/admin/ratelimit", "/admin/threads", "/admin/heap", "/admin/cache/flush")
.build();
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -126,7 +126,7 @@ class BasicAdminResource_RateLimitSnapshot_Test extends TestBase {
.exemptPaths("/admin/ratelimit", "/admin/threads", "/admin/heap", "/admin/cache/flush")
.build();
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -167,7 +167,7 @@ class BasicAdminResource_RateLimitSnapshot_Test extends TestBase {
.exemptPaths("/admin/ratelimit", "/admin/threads", "/admin/heap", "/admin/cache/flush")
.build();
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -232,7 +232,7 @@ class BasicAdminResource_RateLimitSnapshot_Test extends TestBase {
.storage(new E01_NoSnapshotStorage())
.build();
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class E extends RestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_SvlPathOverride_Test.java
index fe0489ac25..94ab1b8ece 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicAdminResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/AdminMixin_SvlPathOverride_Test.java
@@ -27,10 +27,10 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code ${juneau.admin.path:admin}} SVL prefix override on
- * {@link BasicAdminResource}.
+ * {@link AdminMixin}.
*
* <p>
- * Unlike the single-op mixins, {@link BasicAdminResource} declares <i>four</i> distinct ops
+ * Unlike the single-op mixins, {@link AdminMixin} declares <i>four</i> distinct ops
* (threads / heap / cache/flush / ratelimit) sharing a common prefix variable. A single
* override relocates the whole admin surface; the test exercises {@code GET .../threads} as
* the canonical end-to-end check since the other three ops share the same SVL substitution
@@ -44,9 +44,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicAdminResource_SvlPathOverride_Test extends TestBase {
+class AdminMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A01_OverridePath extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -79,7 +79,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A02_BareToken extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
@@ -98,7 +98,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A03_LeadingSlash extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
@@ -117,7 +117,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A04_TrailingSlash extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
@@ -136,7 +136,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A05_BothSlashes extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
@@ -155,7 +155,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A06_WildcardSuffix extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
@@ -174,7 +174,7 @@ class BasicAdminResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicAdminResource.class)
+ @Rest(mixins=AdminMixin.class)
public static class A07_MultiSegment extends RestServlet {
private static final long serialVersionUID = 1L;
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_OpenApiHidden_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_OpenApiHidden_Test.java
index e15affe921..7234658090 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_OpenApiHidden_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_OpenApiHidden_Test.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.*;
*
* <p>
* The host extends vanilla {@link RestServlet} and mounts the three ops mixins plus
- * {@link BasicOpenApiResource} (the OpenAPI generator). The generated spec must list the host's
+ * {@link OpenApiMixin} (the OpenAPI generator). The generated spec must list the host's
* own {@code /items} endpoint but NOT the ops-pack paths.
*
* @since 9.5.0
@@ -41,10 +41,10 @@ class BasicOps_OpenApiHidden_Test extends TestBase {
@Rest(
mixins={
- BasicEchoResource.class,
- BasicAdminResource.class,
- BasicRouteIndexResource.class,
- BasicOpenApiResource.class
+ EchoMixin.class,
+ AdminMixin.class,
+ RouteIndexMixin.class,
+ OpenApiMixin.class
},
debug=@Debug("always"),
swaggerProvider=BasicSwaggerProvider.class
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_ParentChain_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_ParentChain_Test.java
index 9537995850..5cf042e5d0 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_ParentChain_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicOps_ParentChain_Test.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.*;
*
* <p>
* Setup: a single {@link RestServlet} host mounts all three ops mixins
- * ({@link BasicEchoResource}, {@link BasicAdminResource}, {@link BasicRouteIndexResource}) plus a
+ * ({@link EchoMixin}, {@link AdminMixin}, {@link RouteIndexMixin}) plus a
* vanilla {@code /items} op of its own. {@code @Rest(debug=@Debug("always"))} unlocks the echo endpoint;
* an empty {@code @Bean RestGuardList} factory replaces the {@link DenyAllGuard} default to
* unlock the admin endpoints.
@@ -55,13 +55,13 @@ import org.junit.jupiter.api.*;
class BasicOps_ParentChain_Test extends TestBase {
@Rest(
- mixins={BasicEchoResource.class, BasicAdminResource.class, BasicRouteIndexResource.class},
+ mixins={EchoMixin.class, AdminMixin.class, RouteIndexMixin.class},
debug=@Debug("always"))
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items", summary="List items") public String items() { return "items"; }
- // Allow-all guard chain — replaces the BasicAdminResource deny-all default.
+ // Allow-all guard chain — replaces the AdminMixin deny-all default.
@Bean public RestGuardList guards(BeanStore bs) { return RestGuardList.create(bs).build(); }
}
@@ -71,16 +71,16 @@ class BasicOps_ParentChain_Test extends TestBase {
MockRestClient.buildLax(A.class);
var hostCtx = RestContext.getGlobalRegistry().get(A.class);
var ctxs = hostCtx.getMixinContexts();
- assertNotNull(ctxs.get(BasicEchoResource.class), "Echo mixin context registered");
- assertNotNull(ctxs.get(BasicAdminResource.class), "Admin mixin context registered");
- assertNotNull(ctxs.get(BasicRouteIndexResource.class), "RouteIndex mixin context registered");
+ assertNotNull(ctxs.get(EchoMixin.class), "Echo mixin context registered");
+ assertNotNull(ctxs.get(AdminMixin.class), "Admin mixin context registered");
+ assertNotNull(ctxs.get(RouteIndexMixin.class), "RouteIndex mixin context registered");
assertEquals(3, ctxs.size(),
"Expected exactly three mixin contexts; got: " + ctxs.keySet());
}
@Test void a02_echoServesAtPrimaryMount() throws Exception {
// FINISHED-101: /debug/echo/* is no longer a multi-path default. Migration to that
- // secondary alias is covered by BasicEchoResource_SvlPathOverride_Test#a02.
+ // secondary alias is covered by EchoMixin_SvlPathOverride_Test#a02.
c.get("/echo/x").run().assertStatus(200);
c.get("/debug/echo/x").run().assertStatus(404);
}
@@ -114,7 +114,7 @@ class BasicOps_ParentChain_Test extends TestBase {
@Test void a06_legacyRoutesAliasNotMountedByDefault() throws Exception {
// FINISHED-101: /routes is no longer a multi-path default. Migration covered by
- // BasicRouteIndexResource_SvlPathOverride_Test#a02.
+ // RouteIndexMixin_SvlPathOverride_Test#a02.
c.get("/routes").run().assertStatus(404);
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_AsMixin_Test.java
similarity index 86%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_AsMixin_Test.java
index a824b48c6a..006814b777 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_AsMixin_Test.java
@@ -27,7 +27,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicEchoResource} mounted as a mixin via {@code @Rest(mixins=...)} on a vanilla
+ * Validates {@link EchoMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a vanilla
* {@link RestServlet}.
*
* <p>
@@ -38,7 +38,7 @@ import org.junit.jupiter.api.*;
* <li>{@code @Rest(debug=@Debug("always"))} unlocks the endpoint and returns the full echo payload.
* <li>{@code @Rest(debug=@Debug("conditional"))} requires the {@code Debug: true} request header.
* <li>Sensitive headers ({@code Authorization}, {@code Cookie}) are redacted by default.
- * <li>Importer's {@code @Bean BasicEchoResource} factory drives the body cap and redact list.
+ * <li>Importer's {@code @Bean EchoMixin} factory drives the body cap and redact list.
* <li>Body capture truncates correctly when the inbound body exceeds the configured cap.
* <li>Path remainder, query string, and query params are surfaced.
* <li>The handler dispatches on {@code @RestOp(method="*")} — POST and PUT both work.
@@ -47,10 +47,10 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicEchoResource_AsMixin_Test extends TestBase {
+class EchoMixin_AsMixin_Test extends TestBase {
/** Default-host mounting the mixin without {@code @Rest(debug)}. */
- @Rest(mixins=BasicEchoResource.class)
+ @Rest(mixins=EchoMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -73,7 +73,7 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
/** Host with debug always-on so the echo endpoint serves. */
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -112,7 +112,7 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
.getContent().asString();
Assertions.assertFalse(body.contains("Bearer secret-token"),
"Authorization value must NEVER be reflected back; body was: " + body);
- Assertions.assertTrue(body.contains(BasicEchoResource.REDACTED),
+ Assertions.assertTrue(body.contains(EchoMixin.REDACTED),
"Redaction sentinel should appear; body was: " + body);
}
@@ -146,7 +146,7 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
/** Host with conditional debug — requires {@code Debug: true} request header to unlock echo. */
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("conditional"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("conditional"))
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
}
@@ -166,11 +166,11 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
/** Host with a custom redact list and a tight body cap via @Bean factory. */
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class D extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicEchoResource echo() {
- return BasicEchoResource.create()
+ @Bean public EchoMixin echo() {
+ return EchoMixin.create()
.bodyLimit(8L)
.redactHeader("X-Internal-Trace")
.build();
@@ -187,7 +187,7 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
.getContent().asString();
Assertions.assertFalse(body.contains("abc-trace-id"),
"Custom-redacted header value must NOT be reflected back; body was: " + body);
- Assertions.assertTrue(body.contains(BasicEchoResource.REDACTED));
+ Assertions.assertTrue(body.contains(EchoMixin.REDACTED));
}
@Test void d02_authorizationStillRedactedAfterAddingCustom() throws Exception {
@@ -214,11 +214,11 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
/** Host with a zero body cap — every non-empty body truncates immediately. */
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class G extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicEchoResource echo() {
- return BasicEchoResource.create().bodyLimit(0L).build();
+ @Bean public EchoMixin echo() {
+ return EchoMixin.create().bodyLimit(0L).build();
}
}
@@ -236,11 +236,11 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
/** Host with a redactedHeaders(...) replace-list that disables built-in defaults. */
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class E extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicEchoResource echo() {
- return BasicEchoResource.create()
+ @Bean public EchoMixin echo() {
+ return EchoMixin.create()
.redactedHeaders("X-Custom-Only")
.build();
}
@@ -274,36 +274,36 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
@Test void f01_builderRejectsNegativeBodyLimit() {
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicEchoResource.create().bodyLimit(-1L));
+ () -> EchoMixin.create().bodyLimit(-1L));
}
@Test void f02_builderRejectsBlankRedactHeader() {
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicEchoResource.create().redactHeader(""));
+ () -> EchoMixin.create().redactHeader(""));
Assertions.assertThrows(IllegalArgumentException.class,
- () -> BasicEchoResource.create().redactHeader(null));
+ () -> EchoMixin.create().redactHeader(null));
}
@Test void f03_redactedHeadersLowerIsImmutable() {
- var r = BasicEchoResource.create().build();
+ var r = EchoMixin.create().build();
Assertions.assertThrows(UnsupportedOperationException.class,
() -> r.getRedactedHeadersLower().add("X-Test"));
}
@Test void f04_defaultsExposedAsConstants() {
- Assertions.assertEquals(1_048_576L, BasicEchoResource.DEFAULT_BODY_LIMIT);
- Assertions.assertTrue(BasicEchoResource.DEFAULT_REDACTED_HEADERS.contains("Authorization"));
- Assertions.assertTrue(BasicEchoResource.DEFAULT_REDACTED_HEADERS.contains("Cookie"));
+ Assertions.assertEquals(1_048_576L, EchoMixin.DEFAULT_BODY_LIMIT);
+ Assertions.assertTrue(EchoMixin.DEFAULT_REDACTED_HEADERS.contains("Authorization"));
+ Assertions.assertTrue(EchoMixin.DEFAULT_REDACTED_HEADERS.contains("Cookie"));
}
@Test void f05_noArgConstructorMatchesDefaultBuilder() {
- var r = new BasicEchoResource();
- Assertions.assertEquals(BasicEchoResource.DEFAULT_BODY_LIMIT, r.getBodyLimit());
+ var r = new EchoMixin();
+ Assertions.assertEquals(EchoMixin.DEFAULT_BODY_LIMIT, r.getBodyLimit());
Assertions.assertTrue(r.getRedactedHeadersLower().contains("authorization"));
}
@Test void f06_redactedHeadersFiltersNullAndBlank() {
- var r = BasicEchoResource.create()
+ var r = EchoMixin.create()
.redactedHeaders("X-Keep", null, "", " ", "X-Also")
.build();
var s = r.getRedactedHeadersLower();
@@ -313,14 +313,14 @@ class BasicEchoResource_AsMixin_Test extends TestBase {
}
@Test void f07_redactedHeadersNullVarargsClears() {
- var r = BasicEchoResource.create().redactedHeaders((String[]) null).build();
+ var r = EchoMixin.create().redactedHeaders((String[]) null).build();
Assertions.assertTrue(r.getRedactedHeadersLower().isEmpty(),
"null varargs should clear the redact list");
}
@Test void f08_zeroBodyLimitTruncatesEverything() throws Exception {
// Builder accepts 0; the handler then truncates any non-empty body.
- var b = BasicEchoResource.create().bodyLimit(0L).build();
+ var b = EchoMixin.create().bodyLimit(0L).build();
Assertions.assertEquals(0L, b.getBodyLimit());
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_JettyMicroservice_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_JettyMicroservice_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_JettyMicroservice_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_JettyMicroservice_Test.java
index f106120c43..68db6388c2 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_JettyMicroservice_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_JettyMicroservice_Test.java
@@ -34,7 +34,7 @@ import org.junit.jupiter.api.extension.*;
import jakarta.servlet.*;
/**
- * Real-Jetty deployment-parity assertion for {@link BasicEchoResource}.
+ * Real-Jetty deployment-parity assertion for {@link EchoMixin}.
*
* <p>
* Boots a {@link org.apache.juneau.microservice.Microservice Microservice} backed by
@@ -55,13 +55,13 @@ import jakarta.servlet.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.JettyMicroserviceTest
-class BasicEchoResource_JettyMicroservice_Test extends TestBase {
+class EchoMixin_JettyMicroservice_Test extends TestBase {
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class Host extends RestServlet {
private static final long serialVersionUID = 1L;
- @Bean public BasicEchoResource echo() {
- return BasicEchoResource.create()
+ @Bean public EchoMixin echo() {
+ return EchoMixin.create()
.bodyLimit(1024L)
.build();
}
@@ -116,7 +116,7 @@ class BasicEchoResource_JettyMicroservice_Test extends TestBase {
assertEquals(200, resp.statusCode());
assertFalse(resp.body().contains("real-network-secret"),
"Authorization secret must NEVER cross back; body: " + resp.body());
- assertTrue(resp.body().contains(BasicEchoResource.REDACTED));
+ assertTrue(resp.body().contains(EchoMixin.REDACTED));
}
@Test void a03_debugEchoLegacyAliasNotMountedByDefault() throws Exception {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_Springboot_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_Springboot_Test.java
similarity index 89%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_Springboot_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_Springboot_Test.java
index 65ef6a7138..73453acf70 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_Springboot_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_Springboot_Test.java
@@ -36,19 +36,19 @@ import org.springframework.context.annotation.*;
import org.springframework.test.annotation.*;
/**
- * Real-Spring-Boot deployment-parity assertion for {@link BasicEchoResource}.
+ * Real-Spring-Boot deployment-parity assertion for {@link EchoMixin}.
*
* <p>
* Boots a full Spring Boot context with embedded Tomcat on a random port, registers a
* {@link BasicSpringRestServlet}-based host with the echo mixin via
- * {@link ServletRegistrationBean}, supplies a Spring {@code @Bean BasicEchoResource}, and hits
+ * {@link ServletRegistrationBean}, supplies a Spring {@code @Bean EchoMixin}, and hits
* {@code /echo/*} over real HTTP.
*
* <p>
* Catches things {@code MockRest} and the Jetty parity test cannot:
* <ul>
* <li>Spring's bean store adapter ({@code SpringBeanStore}) resolving the host's
- * {@code @Bean BasicEchoResource} during the FINISHED-72 mixin walk through
+ * {@code @Bean EchoMixin} during the FINISHED-72 mixin walk through
* {@link org.springframework.context.ApplicationContext#getBean(Class)
* ApplicationContext.getBean(...)}.
* <li>End-to-end format-pinned JSON ({@link org.apache.juneau.rest.RestResponse#getDirectWriter
@@ -60,10 +60,10 @@ import org.springframework.test.annotation.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.SpringbootTest
-@SpringBootTest(classes = BasicEchoResource_Springboot_Test.TestApp.class,
+@SpringBootTest(classes = EchoMixin_Springboot_Test.TestApp.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class BasicEchoResource_Springboot_Test {
+class EchoMixin_Springboot_Test {
@SpringBootConfiguration
@EnableAutoConfiguration
@@ -75,12 +75,12 @@ class BasicEchoResource_Springboot_Test {
return new ServletRegistrationBean<>(servlet, "/*");
}
- @Bean public BasicEchoResource echoResource() {
- return BasicEchoResource.create().bodyLimit(2048L).build();
+ @Bean public EchoMixin echoResource() {
+ return EchoMixin.create().bodyLimit(2048L).build();
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class Host extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_SvlPathOverride_Test.java
similarity index 89%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_SvlPathOverride_Test.java
index 10ab7dacd9..a9ab4b5699 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicEchoResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/EchoMixin_SvlPathOverride_Test.java
@@ -23,7 +23,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates the {@code ${juneau.echo.path:echo}} SVL override on {@link BasicEchoResource}.
+ * Validates the {@code ${juneau.echo.path:echo}} SVL override on {@link EchoMixin}.
*
* <p>
* Per the FINISHED-101 multi-path collapse, the historical {@code /debug/echo/*} alias (formerly
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.*;
*
* <p>
* Uses {@code @Debug("always")} so the debug guard does not return 404 — the
- * default-deny behavior of {@link BasicEchoResource} is exercised separately in the AsMixin
+ * default-deny behavior of {@link EchoMixin} is exercised separately in the AsMixin
* test suite.
*
* <p>
@@ -42,9 +42,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicEchoResource_SvlPathOverride_Test extends TestBase {
+class EchoMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A01_OverridePath extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -68,7 +68,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A02_DebugEchoAliasMigration extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -92,7 +92,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A03_BareToken extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -110,7 +110,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A04_LeadingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -128,7 +128,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A05_TrailingSlash extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -146,7 +146,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A06_BothSlashes extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -164,7 +164,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A07_WildcardSuffix extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -182,7 +182,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicEchoResource.class, debug=@Debug("always"))
+ @Rest(mixins=EchoMixin.class, debug=@Debug("always"))
public static class A08_MultiSegment extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
@@ -193,7 +193,7 @@ class BasicEchoResource_SvlPathOverride_Test extends TestBase {
// Use debug/echo2 (2-segment) to test multi-segment path normalization while staying
// under the 2-segment SVL path depth that Juneau's UrlPathMatcher reliably supports
// for mixin op-paths. Paths deeper than 2 segments are not tested here to avoid
- // collision with BasicSwaggerResource's /api/* default and potential routing edge cases
+ // collision with SwaggerMixin's /api/* default and potential routing edge cases
// with 3+ segment base paths in SVL-resolved @RestOp patterns.
System.setProperty(key, "/debug/echo2/*");
try {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_AsMixin_Test.java
similarity index 96%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_AsMixin_Test.java
index 86bfff2ace..550ca2015d 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_AsMixin_Test.java
@@ -26,7 +26,7 @@ import org.apache.juneau.rest.servlet.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicRouteIndexResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link RouteIndexMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -46,13 +46,13 @@ import org.junit.jupiter.api.*;
* Per the FINISHED-101 multi-path collapse, the historical {@code /routes} mount alias
* (formerly a dual default on a single op) is now reached via
* {@code -Djuneau.routeindex.path=routes}; that behavior is covered by
- * {@code BasicRouteIndexResource_SvlPathOverride_Test}.
+ * {@code RouteIndexMixin_SvlPathOverride_Test}.
*
* @since 9.5.0
*/
-class BasicRouteIndexResource_AsMixin_Test extends TestBase {
+class RouteIndexMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A extends RestServlet {
private static final long serialVersionUID = 1L;
@@ -150,7 +150,7 @@ class BasicRouteIndexResource_AsMixin_Test extends TestBase {
// -----------------------------------------------------------------------------------------
@Deprecated
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class C extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/c-item", summary="C item",
@@ -182,7 +182,7 @@ class BasicRouteIndexResource_AsMixin_Test extends TestBase {
// ops, e.g. /items) and never expose the route-index endpoint itself.
// -----------------------------------------------------------------------------------------
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class B extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/only") public String only() { return "only"; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_SvlPathOverride_Test.java
index 98f76b5bde..339af9d1d9 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/ops/BasicRouteIndexResource_SvlPathOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/ops/RouteIndexMixin_SvlPathOverride_Test.java
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.*;
/**
* Validates the {@code ${juneau.routeindex.path:options}} SVL override on
- * {@link BasicRouteIndexResource}.
+ * {@link RouteIndexMixin}.
*
* <p>
* Per the FINISHED-101 multi-path collapse, the historical {@code /routes} alias (formerly a
@@ -38,9 +38,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
+class RouteIndexMixin_SvlPathOverride_Test extends TestBase {
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A01_OverridePath extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -66,7 +66,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A02_RoutesAliasMigration extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -91,7 +91,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A03_BareToken extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -110,7 +110,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A04_LeadingSlash extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -129,7 +129,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A05_TrailingSlash extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -148,7 +148,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A06_BothSlashes extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
@@ -167,7 +167,7 @@ class BasicRouteIndexResource_SvlPathOverride_Test extends TestBase {
}
}
- @Rest(mixins=BasicRouteIndexResource.class)
+ @Rest(mixins=RouteIndexMixin.class)
public static class A07_MultiSegment extends RestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/servlet/JuneauRestServletContainerInitializer_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/servlet/JuneauRestServletContainerInitializer_Test.java
index 819a89b551..51ca713071 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/servlet/JuneauRestServletContainerInitializer_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/servlet/JuneauRestServletContainerInitializer_Test.java
@@ -48,9 +48,9 @@ class JuneauRestServletContainerInitializer_Test extends TestBase {
var ctx = mockContext("true", dyn);
new JuneauRestServletContainerInitializer()
- .onStartup(Set.of(BasicVersionServlet.class), ctx);
+ .onStartup(Set.of(VersionServlet.class), ctx);
- verify(ctx).addServlet(eq(BasicVersionServlet.class.getName()), any(BasicVersionServlet.class));
+ verify(ctx).addServlet(eq(VersionServlet.class.getName()), any(VersionServlet.class));
verify(dyn).addMapping("/version/*");
}
@@ -59,7 +59,7 @@ class JuneauRestServletContainerInitializer_Test extends TestBase {
var ctx = mockContext(null, dyn);
new JuneauRestServletContainerInitializer()
- .onStartup(Set.of(BasicVersionServlet.class), ctx);
+ .onStartup(Set.of(VersionServlet.class), ctx);
verify(ctx, never()).addServlet(anyString(), any(Servlet.class));
}
@@ -68,10 +68,10 @@ class JuneauRestServletContainerInitializer_Test extends TestBase {
var dyn = mock(ServletRegistration.Dynamic.class);
var ctx = mockContext("true", dyn);
- // BasicVersionResource is a plain mixin (no top-level paths, not even a RestServlet) — it must
+ // VersionMixin is a plain mixin (no top-level paths, not even a RestServlet) — it must
// be filtered out and never mounted.
new JuneauRestServletContainerInitializer()
- .onStartup(Set.of(BasicVersionResource.class), ctx);
+ .onStartup(Set.of(VersionMixin.class), ctx);
verify(ctx, never()).addServlet(anyString(), any(Servlet.class));
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauRestAutoConfiguration_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauRestAutoConfiguration_Test.java
index 9bab08d88e..6300566a07 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauRestAutoConfiguration_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauRestAutoConfiguration_Test.java
@@ -71,7 +71,7 @@ class JuneauRestAutoConfiguration_Test extends TestBase {
@Configuration
static class ServletOnlyConfig {
@org.springframework.context.annotation.Bean
- Servlet versionServlet() { return new BasicVersionServlet(); }
+ Servlet versionServlet() { return new VersionServlet(); }
}
@Test void b01_mountsRestServletAtSelfDeclaredPath() throws Exception {
@@ -82,18 +82,18 @@ class JuneauRestAutoConfiguration_Test extends TestBase {
new JuneauRestAutoConfiguration().juneauRestAutoRegistrar(appContext).onStartup(servletContext);
- verify(servletContext).addServlet(anyString(), any(BasicVersionServlet.class));
+ verify(servletContext).addServlet(anyString(), any(VersionServlet.class));
verify(dyn).addMapping("/version/*");
}
}
@Configuration
static class ManuallyRegisteredConfig {
- private final BasicVersionServlet servlet = new BasicVersionServlet();
+ private final VersionServlet servlet = new VersionServlet();
@org.springframework.context.annotation.Bean
Servlet versionServlet() { return servlet; }
@org.springframework.context.annotation.Bean
- ServletRegistrationBean<BasicVersionServlet> versionRegistration() {
+ ServletRegistrationBean<VersionServlet> versionRegistration() {
return new ServletRegistrationBean<>(servlet, "/custom/*");
}
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations_Test.java
index b36337b49c..d01e9bc626 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/JuneauServletRegistrations_Test.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.*;
class JuneauServletRegistrations_Test extends TestBase {
@Test void a01_derivesMappingFromAnnotation() {
- var bean = JuneauServletRegistrations.forServlet(new BasicVersionServlet(), null);
+ var bean = JuneauServletRegistrations.forServlet(new VersionServlet(), null);
assertTrue(bean.getUrlMappings().contains("/version/*"),
"Mapping should be derived from @Rest(paths); was: " + bean.getUrlMappings());
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_SpringbootIntegration_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_SpringbootIntegration_Test.java
index 49d622341d..f023683920 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_SpringbootIntegration_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_SpringbootIntegration_Test.java
@@ -50,7 +50,7 @@ import org.springframework.test.context.*;
* </ul>
*
* <p>
- * Mirrors the pattern used by {@code BasicStaticFilesResource_Springboot_Test} and friends:
+ * Mirrors the pattern used by {@code StaticFilesMixin_Springboot_Test} and friends:
* minimal {@code @SpringBootConfiguration} class, no web environment, dirty context after the
* class so subsequent tests don't see the bridge.
*/
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_Test.java
index ce00bfbc35..a7b9621cdd 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/springboot/SpringEnvironmentPropertySource_Test.java
@@ -44,8 +44,8 @@ import org.springframework.mock.env.*;
*
* <p>
* A full {@code @SpringBootTest} bootstrap (with {@code application.yaml} on the classpath) is
- * exercised indirectly through the existing {@code BasicStaticFilesResource_Springboot_Test} and
- * {@code BasicEchoResource_Springboot_Test} smoke tests — those already build a real Spring
+ * exercised indirectly through the existing {@code StaticFilesMixin_Springboot_Test} and
+ * {@code EchoMixin_Springboot_Test} smoke tests — those already build a real Spring
* context which now installs the bridge automatically via {@link SpringBeanStore}'s constructor.
* This test keeps the focus on the bridge itself.
*/
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_AsMixin_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_AsMixin_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_AsMixin_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_AsMixin_Test.java
index 9ae12e5a28..aaeb2001eb 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_AsMixin_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_AsMixin_Test.java
@@ -25,7 +25,7 @@ import org.apache.juneau.rest.staticfile.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicStaticFilesResource} mounted as a mixin via {@code @Rest(mixins=...)} on a
+ * Validates {@link StaticFilesMixin} mounted as a mixin via {@code @Rest(mixins=...)} on a
* vanilla {@link RestServlet}.
*
* <p>
@@ -45,13 +45,13 @@ import org.junit.jupiter.api.*;
* and {@code htdocs/} directories — only the URL-side mount is now single. Per the
* FINISHED-101 multi-path collapse, the {@code /htdocs/*} mount alias (formerly a dual default)
* is now reached via {@code -Djuneau.staticfiles.path=htdocs}; that behavior is covered by
- * {@code BasicStaticFilesResource_SvlPathOverride_Test}.
+ * {@code StaticFilesMixin_SvlPathOverride_Test}.
*
* @since 9.5.0
*/
-class BasicStaticFilesResource_AsMixin_Test extends TestBase {
+class StaticFilesMixin_AsMixin_Test extends TestBase {
- @Rest(mixins=BasicStaticFilesResource.class)
+ @Rest(mixins=StaticFilesMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
@RestGet(path="/items") public String items() { return "items"; }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_CacheControl_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_CacheControl_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_CacheControl_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_CacheControl_Test.java
index a25d01695e..1561f69bee 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_CacheControl_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_CacheControl_Test.java
@@ -24,7 +24,7 @@ import org.apache.juneau.rest.staticfile.*;
import org.junit.jupiter.api.*;
/**
- * Validates that {@link BasicStaticFilesResource} preserves the default
+ * Validates that {@link StaticFilesMixin} preserves the default
* {@code Cache-Control: max-age=86400, public} header end-to-end (the default supplied by
* {@link BasicStaticFiles}).
*
@@ -40,9 +40,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicStaticFilesResource_CacheControl_Test extends TestBase {
+class StaticFilesMixin_CacheControl_Test extends TestBase {
- @Rest(mixins=BasicStaticFilesResource.class)
+ @Rest(mixins=StaticFilesMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_ImporterOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_ImporterOverride_Test.java
similarity index 94%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_ImporterOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_ImporterOverride_Test.java
index 0a865e0bc1..7490db652c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_ImporterOverride_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_ImporterOverride_Test.java
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.*;
/**
* Validates that an importer's {@code @Bean StaticFiles} factory method overrides the default
- * {@link BasicStaticFiles} configuration when mounted alongside {@link BasicStaticFilesResource}.
+ * {@link BasicStaticFiles} configuration when mounted alongside {@link StaticFilesMixin}.
*
* <p>
* The importer below declares a custom {@code StaticFiles} bean with a non-default
@@ -38,9 +38,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicStaticFilesResource_ImporterOverride_Test extends TestBase {
+class StaticFilesMixin_ImporterOverride_Test extends TestBase {
- @Rest(mixins=BasicStaticFilesResource.class)
+ @Rest(mixins=StaticFilesMixin.class)
public static class A extends BasicRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_JettyMicroservice_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_JettyMicroservice_Test.java
similarity index 96%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_JettyMicroservice_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_JettyMicroservice_Test.java
index 21149081a3..51189b08f5 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_JettyMicroservice_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_JettyMicroservice_Test.java
@@ -35,7 +35,7 @@ import org.junit.jupiter.api.extension.*;
import jakarta.servlet.*;
/**
- * Real-Jetty deployment-parity assertion for {@link BasicStaticFilesResource}.
+ * Real-Jetty deployment-parity assertion for {@link StaticFilesMixin}.
*
* <p>
* Boots a {@link org.apache.juneau.microservice.Microservice Microservice} backed by
@@ -62,10 +62,10 @@ import jakarta.servlet.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.JettyMicroserviceTest
-class BasicStaticFilesResource_JettyMicroservice_Test extends TestBase {
+class StaticFilesMixin_JettyMicroservice_Test extends TestBase {
/** Test host: vanilla {@link BasicRestServlet} subclass with the static-files mixin attached. */
- @Rest(mixins=BasicStaticFilesResource.class)
+ @Rest(mixins=StaticFilesMixin.class)
public static class Host extends BasicRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_OpenApiHidden_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_OpenApiHidden_Test.java
similarity index 89%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_OpenApiHidden_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_OpenApiHidden_Test.java
index 7f58ad546f..fed532400f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_OpenApiHidden_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_OpenApiHidden_Test.java
@@ -28,11 +28,11 @@ import org.junit.jupiter.api.*;
/**
* Validates that the static-files mixin's greedy {@code /static/*} handler is excluded from the
* generated Swagger/OpenAPI spec, per {@link OpSwagger#ignore() @OpSwagger(ignore=true)} on
- * {@link BasicStaticFilesResource#getStaticFile} and the matching HEAD handler.
+ * {@link StaticFilesMixin#getStaticFile} and the matching HEAD handler.
*
* <p>
- * The host below mounts both {@link BasicStaticFilesResource} (static-file serving) and
- * {@link BasicOpenApiResource} (OpenAPI generator) as mixins on a vanilla {@link RestServlet}
+ * The host below mounts both {@link StaticFilesMixin} (static-file serving) and
+ * {@link OpenApiMixin} (OpenAPI generator) as mixins on a vanilla {@link RestServlet}
* (NOT {@link BasicRestServlet}) so the legacy
* {@code BasicRestOperations.getHtdoc(...)} method does not pollute the spec independently
* of what the mixin emits. The generated spec must list the host's own {@code /items} endpoint
@@ -40,7 +40,7 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicStaticFilesResource_OpenApiHidden_Test extends TestBase {
+class StaticFilesMixin_OpenApiHidden_Test extends TestBase {
/**
* Host extends vanilla {@link RestServlet} (NOT {@link BasicRestServlet}) so the legacy
@@ -49,7 +49,7 @@ class BasicStaticFilesResource_OpenApiHidden_Test extends TestBase {
* generate; we wire it explicitly via {@link Rest#swaggerProvider}.
*/
@Rest(
- mixins={BasicStaticFilesResource.class, BasicOpenApiResource.class},
+ mixins={StaticFilesMixin.class, OpenApiMixin.class},
swaggerProvider=BasicSwaggerProvider.class
)
public static class A extends RestServlet {
@@ -60,7 +60,7 @@ class BasicStaticFilesResource_OpenApiHidden_Test extends TestBase {
private static final MockRestClient c = MockRestClient.buildLax(A.class);
@Test void a01_openapiSpecExcludesStaticPaths() throws Exception {
- // /openapi.json is format-pinned to JSON regardless of Accept (per BasicOpenApiResource);
+ // /openapi.json is format-pinned to JSON regardless of Accept (per OpenApiMixin);
// avoids the need to register JSON serializers on the vanilla RestServlet host.
var spec = c.get("/openapi.json")
.run()
@@ -79,7 +79,7 @@ class BasicStaticFilesResource_OpenApiHidden_Test extends TestBase {
.run()
.assertStatus(200);
// FINISHED-101: /htdocs/* is no longer a multi-path default; migration covered by
- // BasicStaticFilesResource_SvlPathOverride_Test#a02.
+ // StaticFilesMixin_SvlPathOverride_Test#a02.
c.get("/htdocs/javadoc.css")
.run()
.assertStatus(404);
@@ -87,7 +87,7 @@ class BasicStaticFilesResource_OpenApiHidden_Test extends TestBase {
/**
* Host that exercises the LEGACY static-file path: a {@link BasicRestServlet} subclass with
- * the api-docs mixin pack inherited and no explicit {@link BasicStaticFilesResource}. The
+ * the api-docs mixin pack inherited and no explicit {@link StaticFilesMixin}. The
* legacy {@code getHtdoc(...)} method on {@code BasicRestOperations} now carries
* {@code @OpSwagger(ignore=true)} so {@code /htdocs/*} must NOT appear in the generated spec
* even when the new mixin is not mounted.
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SpringbootMetaInf_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_SpringbootMetaInf_Test.java
similarity index 94%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SpringbootMetaInf_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_SpringbootMetaInf_Test.java
index 566de728e5..745e3ca86e 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SpringbootMetaInf_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_SpringbootMetaInf_Test.java
@@ -38,7 +38,7 @@ import org.springframework.context.annotation.*;
import org.springframework.test.annotation.*;
/**
- * Spring Boot {@code META-INF/resources/} bridge test for {@link BasicStaticFilesResource}.
+ * Spring Boot {@code META-INF/resources/} bridge test for {@link StaticFilesMixin}.
*
* <p>
* Spring Boot's embedded Tomcat / Jetty auto-serves files placed under the conventional
@@ -56,16 +56,16 @@ import org.springframework.test.annotation.*;
* {@code juneau-utest/src/test/resources/META-INF/resources/spring-fixture.txt}.
*
* <p>
- * Companion to {@link BasicStaticFilesResource_Springboot_Test} which exercises the default
+ * Companion to {@link StaticFilesMixin_Springboot_Test} which exercises the default
* classpath ({@code static/} + {@code htdocs/}) under the same Spring Boot wiring.
*
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.SpringbootTest
-@SpringBootTest(classes = BasicStaticFilesResource_SpringbootMetaInf_Test.TestApp.class,
+@SpringBootTest(classes = StaticFilesMixin_SpringbootMetaInf_Test.TestApp.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class BasicStaticFilesResource_SpringbootMetaInf_Test {
+class StaticFilesMixin_SpringbootMetaInf_Test {
@SpringBootConfiguration
@EnableAutoConfiguration
@@ -87,7 +87,7 @@ class BasicStaticFilesResource_SpringbootMetaInf_Test {
* an importer-supplied {@code StaticFiles} factory that adds {@code /META-INF/resources/} to
* the classpath search list.
*/
- @Rest(mixins = BasicStaticFilesResource.class)
+ @Rest(mixins = StaticFilesMixin.class)
public static class Host extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Springboot_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Springboot_Test.java
similarity index 94%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Springboot_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Springboot_Test.java
index edf0055907..2d524c5617 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Springboot_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Springboot_Test.java
@@ -37,7 +37,7 @@ import org.springframework.context.annotation.*;
import org.springframework.test.annotation.*;
/**
- * Real-Spring-Boot deployment-parity assertion for {@link BasicStaticFilesResource}.
+ * Real-Spring-Boot deployment-parity assertion for {@link StaticFilesMixin}.
*
* <p>
* Boots a full Spring Boot context with embedded Tomcat on a random port, registers a
@@ -46,7 +46,7 @@ import org.springframework.test.annotation.*;
* real HTTP.
*
* <p>
- * Catches things {@code MockRest} and the {@link BasicStaticFilesResource_JettyMicroservice_Test
+ * Catches things {@code MockRest} and the {@link StaticFilesMixin_JettyMicroservice_Test
* Jetty parity test} cannot:
* <ul>
* <li>Spring's bean store adapter ({@code SpringBeanStore}) resolving Juneau {@code StaticFiles}
@@ -63,10 +63,10 @@ import org.springframework.test.annotation.*;
* @since 9.5.0
*/
@org.apache.juneau.testing.annotations.SpringbootTest
-@SpringBootTest(classes = BasicStaticFilesResource_Springboot_Test.TestApp.class,
+@SpringBootTest(classes = StaticFilesMixin_Springboot_Test.TestApp.class,
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
-class BasicStaticFilesResource_Springboot_Test {
+class StaticFilesMixin_Springboot_Test {
/**
* Minimal Spring Boot application that registers a single {@link Host} servlet at {@code /*}.
@@ -89,7 +89,7 @@ class BasicStaticFilesResource_Springboot_Test {
/**
* Test host: subclass of {@link BasicSpringRestServlet} carrying the static-files mixin.
*/
- @Rest(mixins = BasicStaticFilesResource.class)
+ @Rest(mixins = StaticFilesMixin.class)
public static class Host extends BasicSpringRestServlet {
private static final long serialVersionUID = 1L;
}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Standalone_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Standalone_Test.java
similarity index 87%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Standalone_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Standalone_Test.java
index c85625170c..ff61f1a2b3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_Standalone_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_Standalone_Test.java
@@ -23,8 +23,8 @@ import org.apache.juneau.rest.staticfile.*;
import org.junit.jupiter.api.*;
/**
- * Validates {@link BasicStaticFilesResource} deployed as a <em>standalone</em> resource (Path B
- * in TODO-75) — the user extends {@code BasicStaticFilesResource} directly and the
+ * Validates {@link StaticFilesMixin} deployed as a <em>standalone</em> resource (Path B
+ * in TODO-75) — the user extends {@code StaticFilesMixin} directly and the
* inherited op-level {@code @RestGet(path="/${juneau.staticfiles.path:static}/*")} declares the
* mount point without any additional configuration.
*
@@ -34,7 +34,7 @@ import org.junit.jupiter.api.*;
* per op" principle the historical dual default ({@code "/static/*"} + {@code "/htdocs/*"}) was
* collapsed to a single SVL-configurable path; the {@code /htdocs/*} alias is reached via
* {@code -Djuneau.staticfiles.path=htdocs} and is covered by
- * {@code BasicStaticFilesResource_SvlPathOverride_Test#a02}.
+ * {@code StaticFilesMixin_SvlPathOverride_Test#a02}.
*
* <p>
* {@code MockRest} dispatches directly to the inner matcher and does NOT model the
@@ -44,9 +44,9 @@ import org.junit.jupiter.api.*;
*
* @since 9.5.0
*/
-class BasicStaticFilesResource_Standalone_Test extends TestBase {
+class StaticFilesMixin_Standalone_Test extends TestBase {
- public static class CdnResource extends BasicStaticFilesResource { }
+ public static class CdnResource extends StaticFilesMixin { }
private static final MockRestClient c = MockRestClient.buildLax(CdnResource.class);
@@ -59,7 +59,7 @@ class BasicStaticFilesResource_Standalone_Test extends TestBase {
@Test void a02_legacyHtdocsAliasNotMountedByDefault() throws Exception {
// FINISHED-101: /htdocs/* is no longer a multi-path default. Migration covered by
- // BasicStaticFilesResource_SvlPathOverride_Test#a02.
+ // StaticFilesMixin_SvlPathOverride_Test#a02.
c.get("/htdocs/javadoc.css")
.run()
.assertStatus(404);
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SvlPathOverride_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_SvlPathOverride_Test.java
similarity index 93%
rename from juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SvlPathOverride_Test.java
rename to juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/StaticFilesMixin_SvlPathOverride_Test.java
index b474c9c509..40bdaf5f86 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/staticfiles/BasicStaticFilesResource_SvlPathOverride_Test.java
... 1380 lines suppressed ...