Update method names in FragmentsRendering

Closes gh-33974
This commit is contained in:
rstoyanchev 2024-11-27 11:21:19 +00:00
parent 186f909c96
commit 81ea35c726
11 changed files with 173 additions and 55 deletions

View File

@ -466,7 +466,7 @@ Java::
----
@GetMapping
FragmentsRendering handle() {
return FragmentsRendering.with("posts").fragment("comments").build();
return FragmentsRendering.fragment("posts").fragment("comments").build();
}
----
@ -476,7 +476,7 @@ Kotlin::
----
@GetMapping
fun handle(): FragmentsRendering {
return FragmentsRendering.with("posts").fragment("comments").build()
return FragmentsRendering.fragment("posts").fragment("comments").build()
}
----
======

View File

@ -48,7 +48,7 @@ Java::
----
@GetMapping
FragmentsRendering handle() {
return FragmentsRendering.with("posts").fragment("comments").build();
return FragmentsRendering.fragment("posts").fragment("comments").build();
}
----
@ -58,7 +58,7 @@ Kotlin::
----
@GetMapping
fun handle(): FragmentsRendering {
return FragmentsRendering.with("posts").fragment("comments").build()
return FragmentsRendering.fragment("posts").fragment("comments").build()
}
----
======

View File

@ -49,8 +49,8 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
@Nullable
private HttpHeaders headers;
DefaultFragmentsRenderingBuilder(Collection<Fragment> fragments) {
this.fragmentsCollection = new ArrayList<>(fragments);
DefaultFragmentsRenderingBuilder() {
this.fragmentsCollection = null;
this.fragmentsFlux = null;
}
@ -84,22 +84,28 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
return this.headers;
}
@Override
public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) {
return fragment(Fragment.create(viewName, model));
}
@Override
public FragmentsRendering.Builder fragment(String viewName) {
return fragment(Fragment.create(viewName));
}
@Override
public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) {
return fragment(Fragment.create(viewName, model));
}
@Override
public FragmentsRendering.Builder fragment(Fragment fragment) {
initFragmentsCollection().add(fragment);
return this;
}
@Override
public FragmentsRendering.Builder fragments(Collection<Fragment> fragments) {
initFragmentsCollection().addAll(fragments);
return this;
}
private Collection<Fragment> initFragmentsCollection() {
if (this.fragmentsCollection == null) {
this.fragmentsCollection = new ArrayList<>();

View File

@ -17,7 +17,6 @@
package org.springframework.web.reactive.result.view;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@ -65,25 +64,27 @@ public interface FragmentsRendering {
Flux<Fragment> fragments();
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return this builder
* @since 6.2.1
*/
static Builder fragment(String viewName) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName);
}
/**
* Create a builder with one HTML fragment.
* @param viewName the view name for the fragment
* @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return this builder
* @since 6.2.1
*/
static Builder with(String viewName, Map<String, Object> model) {
return withCollection(List.of(Fragment.create(viewName, model)));
}
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return this builder
*/
static Builder with(String viewName) {
return withCollection(List.of(Fragment.create(viewName)));
static Builder fragment(String viewName, Map<String, Object> model) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName, model);
}
/**
@ -91,9 +92,10 @@ public interface FragmentsRendering {
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return the created builder
* @since 6.2.1
*/
static Builder withCollection(Collection<Fragment> fragments) {
return new DefaultFragmentsRenderingBuilder(fragments);
static Builder fragments(Collection<Fragment> fragments) {
return new DefaultFragmentsRenderingBuilder().fragments(fragments);
}
/**
@ -101,24 +103,83 @@ public interface FragmentsRendering {
* @param fragmentsPublisher the fragments to add; each fragment also
* inherits model attributes from the shared model for the request
* @return the created builder
* @since 6.2.1
*/
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) {
static <P extends Publisher<Fragment>> Builder fragmentsPublisher(P fragmentsPublisher) {
return new DefaultFragmentsRenderingBuilder(fragmentsPublisher);
}
/**
* Variant of {@link #withPublisher(Publisher)} that allows using any
* Variant of {@link #fragmentsPublisher(Publisher)} that allows using any
* producer that can be resolved to {@link Publisher} via
* {@link ReactiveAdapterRegistry}.
* @since 6.2.1
*/
static Builder withProducer(Object fragmentsProducer) {
return new DefaultFragmentsRenderingBuilder(adaptProducer(fragmentsProducer));
static Builder fragmentsProducer(Object fragmentsProducer) {
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(fragmentsProducer.getClass());
Assert.isTrue(adapter != null, "Unknown producer " + fragmentsProducer.getClass());
Publisher<Fragment> publisher = adapter.toPublisher(fragmentsProducer);
return fragmentsPublisher(publisher);
}
private static Publisher<Fragment> adaptProducer(Object producer) {
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(producer.getClass());
Assert.isTrue(adapter != null, "Unknown producer " + producer.getClass());
return adapter.toPublisher(producer);
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return this builder
* @deprecated in favor of {@link #fragment(String)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder with(String viewName) {
return fragment(viewName);
}
/**
* Create a builder with one HTML fragment.
* @param viewName the view name for the fragment
* @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return this builder
* @deprecated in favor of {@link #fragment(String, Map)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder with(String viewName, Map<String, Object> model) {
return fragment(viewName, model);
}
/**
* Create a builder with multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return the created builder
* @deprecated in favor of {@link #fragments(Collection)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder withCollection(Collection<Fragment> fragments) {
return fragments(fragments);
}
/**
* Create a builder with a {@link Publisher} of fragments.
* @param fragmentsPublisher the fragments to add; each fragment also
* inherits model attributes from the shared model for the request
* @return the created builder
* @deprecated in favor of {@link #fragmentsPublisher(Publisher)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) {
return fragmentsPublisher(fragmentsPublisher);
}
/**
* Variant of {@link #fragmentsPublisher(Publisher)} that allows using any
* producer that can be resolved to {@link Publisher} via
* {@link ReactiveAdapterRegistry}.
* @deprecated in favor of {@link #fragmentsProducer(Object)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder withProducer(Object fragmentsProducer) {
return fragmentsProducer(fragmentsProducer);
}
@ -169,11 +230,21 @@ public interface FragmentsRendering {
/**
* Add an HTML fragment.
* @param fragment the fragment to add
* @param fragment the fragment to add; the fragment also inherits
* attributes from the shared model for the request
* @return this builder
*/
Builder fragment(Fragment fragment);
/**
* Add HTML fragments.
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return this builder
* @since 6.2.1
*/
Builder fragments(Collection<Fragment> fragments);
/**
* Build the {@link FragmentsRendering} instance.
*/

View File

@ -208,7 +208,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport imp
if (adapter != null) {
if (adapter.isMultiValue()) {
valueMono = (result.getReturnValue() != null ?
Mono.just(FragmentsRendering.withPublisher(adapter.toPublisher(result.getReturnValue())).build()) :
Mono.just(FragmentsRendering.fragmentsPublisher(adapter.toPublisher(result.getReturnValue())).build()) :
Mono.empty());
valueType = ResolvableType.forClass(FragmentsRendering.class);
@ -242,7 +242,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport imp
}
if (Collection.class.isAssignableFrom(clazz)) {
returnValue = FragmentsRendering.withCollection((Collection<Fragment>) returnValue).build();
returnValue = FragmentsRendering.fragments((Collection<Fragment>) returnValue).build();
clazz = FragmentsRendering.class;
}

View File

@ -64,9 +64,9 @@ public class FragmentViewResolutionResultHandlerTests {
static Stream<Arguments> arguments() {
Flux<Fragment> fragmentFlux = Flux.just(fragment1, fragment2).subscribeOn(Schedulers.boundedElastic());
return Stream.of(
Arguments.of(FragmentsRendering.withPublisher(fragmentFlux).build(),
Arguments.of(FragmentsRendering.fragmentsPublisher(fragmentFlux).build(),
on(Handler.class).resolveReturnType(FragmentsRendering.class)),
Arguments.of(FragmentsRendering.withCollection(List.of(fragment1, fragment2)).build(),
Arguments.of(FragmentsRendering.fragments(List.of(fragment1, fragment2)).build(),
on(Handler.class).resolveReturnType(FragmentsRendering.class)),
Arguments.of(fragmentFlux,
on(Handler.class).resolveReturnType(Flux.class, Fragment.class)),

View File

@ -92,7 +92,7 @@ public class ModelAndViewMethodReturnValueHandler implements HandlerMethodReturn
}
if (returnValue instanceof Collection<?> mavs) {
returnValue = FragmentsRendering.with((Collection<ModelAndView>) mavs).build();
returnValue = FragmentsRendering.fragments((Collection<ModelAndView>) mavs).build();
}
if (returnValue instanceof FragmentsRendering rendering) {

View File

@ -393,7 +393,7 @@ public class ResponseBodyEmitterReturnValueHandler implements HandlerMethodRetur
FragmentHttpServletResponse fragmentResponse =
new FragmentHttpServletResponse(this.response, this.charset);
FragmentsRendering render = FragmentsRendering.with(List.of(modelAndView)).build();
FragmentsRendering render = FragmentsRendering.fragments(List.of(modelAndView)).build();
render.resolveNestedViews(this::resolveViewName, this.locale);
render.render(modelAndView.getModel(), this.request, fragmentResponse);

View File

@ -54,37 +54,77 @@ public interface FragmentsRendering extends SmartView {
HttpHeaders headers();
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return the created builder
* @since 6.2.1
*/
static Builder fragment(String viewName) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName);
}
/**
* Create a builder with one HTML fragment.
* @param viewName the view name for the fragment
* @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return the created builder
* @since 6.2.1
*/
static Builder with(String viewName, Map<String, Object> model) {
static Builder fragment(String viewName, Map<String, Object> model) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName, model);
}
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return the created builder
*/
static Builder with(String viewName) {
return new DefaultFragmentsRenderingBuilder().fragment(viewName);
}
/**
* Create a builder with multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return the created builder
* @since 6.2.1
*/
static Builder with(Collection<ModelAndView> fragments) {
static Builder fragments(Collection<ModelAndView> fragments) {
return new DefaultFragmentsRenderingBuilder().fragments(fragments);
}
/**
* Create a builder with one HTML fragment, also inheriting attributes from
* the shared model for the request.
* @param viewName the name of the view for the fragment
* @return the created builder
* @deprecated in favor of {@link #fragment(String)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder with(String viewName) {
return fragment(viewName);
}
/**
* Create a builder with one HTML fragment.
* @param viewName the view name for the fragment
* @param model attributes for the fragment, in addition to attributes from the
* shared model for the request
* @return the created builder
* @deprecated in favor of {@link #fragment(String, Map)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder with(String viewName, Map<String, Object> model) {
return fragment(viewName, model);
}
/**
* Create a builder with multiple HTML fragments.
* @param fragments the fragments to add; each fragment also inherits
* attributes from the shared model for the request
* @return the created builder
* @deprecated in favor of {@link #fragments(Collection)}
*/
@Deprecated(since = "6.2.1", forRemoval = true)
static Builder with(Collection<ModelAndView> fragments) {
return fragments(fragments);
}
/**
* Defines a builder for {@link FragmentsRendering}.

View File

@ -91,7 +91,7 @@ class ModelAndViewMethodReturnValueHandlerTests {
@Test
void handleFragmentsRendering() throws Exception {
FragmentsRendering rendering = FragmentsRendering.with("viewName").build();
FragmentsRendering rendering = FragmentsRendering.fragment("viewName").build();
handler.handleReturnValue(rendering, returnParamModelAndView, mavContainer, webRequest);
assertThat(mavContainer.getView()).isInstanceOf(SmartView.class);

View File

@ -56,7 +56,8 @@ public class DefaultFragmentsRenderingTests {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
FragmentsRendering view = FragmentsRendering.with("fragment1", Map.of("foo", "Foo"))
FragmentsRendering view = FragmentsRendering
.fragment("fragment1", Map.of("foo", "Foo"))
.fragment("fragment2", Map.of("bar", "Bar"))
.header("headerName", "headerValue")
.build();