Skip to content

Commit 715bc68

Browse files
committed
Rename methods in FragmentsRendering
Previous commit 81ea35c in main for 7.0 should have been applied in 6.2.x first for 6.2.1. This commit applies the changes in 6.2.x as intended, effective as of 6.2.13. Closes gh-33974
1 parent 9c24f7b commit 715bc68

File tree

11 files changed

+181
-81
lines changed

11 files changed

+181
-81
lines changed

framework-docs/modules/ROOT/pages/web/webflux-view.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ Java::
448448
----
449449
@GetMapping
450450
FragmentsRendering handle() {
451-
return FragmentsRendering.with("posts").fragment("comments").build();
451+
return FragmentsRendering.fragment("posts").fragment("comments").build();
452452
}
453453
----
454454
@@ -458,7 +458,7 @@ Kotlin::
458458
----
459459
@GetMapping
460460
fun handle(): FragmentsRendering {
461-
return FragmentsRendering.with("posts").fragment("comments").build()
461+
return FragmentsRendering.fragment("posts").fragment("comments").build()
462462
}
463463
----
464464
======

framework-docs/modules/ROOT/pages/web/webmvc-view/mvc-fragments.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Java::
4848
----
4949
@GetMapping
5050
FragmentsRendering handle() {
51-
return FragmentsRendering.with("posts").fragment("comments").build();
51+
return FragmentsRendering.fragment("posts").fragment("comments").build();
5252
}
5353
----
5454
@@ -58,7 +58,7 @@ Kotlin::
5858
----
5959
@GetMapping
6060
fun handle(): FragmentsRendering {
61-
return FragmentsRendering.with("posts").fragment("comments").build()
61+
return FragmentsRendering.fragment("posts").fragment("comments").build()
6262
}
6363
----
6464
======

spring-webflux/src/main/java/org/springframework/web/reactive/result/view/DefaultFragmentsRenderingBuilder.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class DefaultFragmentsRenderingBuilder implements FragmentsRendering.Builder {
4949
@Nullable
5050
private HttpHeaders headers;
5151

52-
DefaultFragmentsRenderingBuilder(Collection<Fragment> fragments) {
53-
this.fragmentsCollection = new ArrayList<>(fragments);
52+
DefaultFragmentsRenderingBuilder() {
53+
this.fragmentsCollection = null;
5454
this.fragmentsFlux = null;
5555
}
5656

@@ -85,13 +85,13 @@ private HttpHeaders initHeaders() {
8585
}
8686

8787
@Override
88-
public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) {
89-
return fragment(Fragment.create(viewName, model));
88+
public FragmentsRendering.Builder fragment(String viewName) {
89+
return fragment(Fragment.create(viewName));
9090
}
9191

9292
@Override
93-
public FragmentsRendering.Builder fragment(String viewName) {
94-
return fragment(Fragment.create(viewName));
93+
public FragmentsRendering.Builder fragment(String viewName, Map<String, Object> model) {
94+
return fragment(Fragment.create(viewName, model));
9595
}
9696

9797
@Override
@@ -100,6 +100,12 @@ public FragmentsRendering.Builder fragment(Fragment fragment) {
100100
return this;
101101
}
102102

103+
@Override
104+
public FragmentsRendering.Builder fragments(Collection<Fragment> fragments) {
105+
initFragmentsCollection().addAll(fragments);
106+
return this;
107+
}
108+
103109
private Collection<Fragment> initFragmentsCollection() {
104110
if (this.fragmentsCollection == null) {
105111
this.fragmentsCollection = new ArrayList<>();

spring-webflux/src/main/java/org/springframework/web/reactive/result/view/FragmentsRendering.java

Lines changed: 97 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.springframework.web.reactive.result.view;
1818

1919
import java.util.Collection;
20-
import java.util.List;
2120
import java.util.Map;
2221
import java.util.function.Consumer;
2322

@@ -32,13 +31,16 @@
3231
import org.springframework.util.Assert;
3332

3433
/**
35-
* Public API for HTML rendering of a collection of fragments each with a view
36-
* and independent model. For use with frontends technologies such as
34+
* Public API to render HTML fragments. A fragment is a portion of an HTML page.
35+
* Normally HTML is rendered with a single model and view. This API allows
36+
* using multiple model and view pairs, one for each HTML fragment.
37+
*
38+
* <p>For use with frontends technologies such as
3739
* <a href="https://htmx.org/">htmx</a> where multiple page fragments may be
38-
* rendered in one response. Supported as a return value from Spring WebFlux
39-
* controller methods.
40+
* rendered in one response.
4041
*
41-
* <p>For full page rendering with a single model and view, use {@link Rendering}.
42+
* <p>Supported as a return value from annotated controller methods.
43+
* For full page rendering with a single model and view, use {@link Rendering}.
4244
*
4345
* @author Rossen Stoyanchev
4446
* @since 6.2
@@ -63,59 +65,107 @@ public interface FragmentsRendering {
6365

6466

6567
/**
66-
* Create a builder and add a fragment with a view name and a model.
68+
* Create a builder with one HTML fragment, also inheriting attributes from
69+
* the shared model for the request.
6770
* @param viewName the name of the view for the fragment
68-
* @param model attributes for the fragment in addition to model
69-
* attributes inherited from the model for the request
7071
* @return this builder
72+
* @since 6.2.13
7173
*/
72-
static Builder with(String viewName, Map<String, Object> model) {
73-
return withCollection(List.of(Fragment.create(viewName, model)));
74+
static Builder fragment(String viewName) {
75+
return new DefaultFragmentsRenderingBuilder().fragment(viewName);
7476
}
7577

7678
/**
77-
* Variant of {@link #with(String, Map)} with a view name only, but also
78-
* inheriting model attributes from the shared model for the request.
79-
* @param viewName the name of the view for the fragment
79+
* Create a builder with one HTML fragment.
80+
* @param viewName the view name for the fragment
81+
* @param model attributes for the fragment, in addition to attributes from the
82+
* shared model for the request
8083
* @return this builder
84+
* @since 6.2.13
8185
*/
82-
static Builder with(String viewName) {
83-
return withCollection(List.of(Fragment.create(viewName)));
86+
static Builder fragment(String viewName, Map<String, Object> model) {
87+
return new DefaultFragmentsRenderingBuilder().fragment(viewName, model);
8488
}
8589

8690
/**
87-
* Variant of {@link #with(String, Map)} with a collection of fragments.
88-
* @param fragments the fragments to add; each fragment also inherits model
91+
* Create a builder with multiple HTML fragments.
92+
* @param fragments the fragments to add; each fragment also inherits
8993
* attributes from the shared model for the request
9094
* @return the created builder
95+
* @since 6.2.13
9196
*/
92-
static Builder withCollection(Collection<Fragment> fragments) {
93-
return new DefaultFragmentsRenderingBuilder(fragments);
97+
static Builder fragments(Collection<Fragment> fragments) {
98+
return new DefaultFragmentsRenderingBuilder().fragments(fragments);
9499
}
95100

96101
/**
97-
* Variant of {@link #with(String, Map)} with a {@link Publisher} of fragments.
102+
* Create a builder with a {@link Publisher} of fragments.
98103
* @param fragmentsPublisher the fragments to add; each fragment also
99104
* inherits model attributes from the shared model for the request
100105
* @return the created builder
106+
* @since 6.2.13
101107
*/
102-
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) {
108+
static <P extends Publisher<Fragment>> Builder fragmentsPublisher(P fragmentsPublisher) {
103109
return new DefaultFragmentsRenderingBuilder(fragmentsPublisher);
104110
}
105111

106112
/**
107-
* Variant of {@link #withPublisher(Publisher)} that allows using any
113+
* Variant of {@link #fragmentsPublisher(Publisher)} that allows using any
108114
* producer that can be resolved to {@link Publisher} via
109115
* {@link ReactiveAdapterRegistry}.
116+
* @since 6.2.13
110117
*/
111-
static Builder withProducer(Object fragmentsProducer) {
112-
return new DefaultFragmentsRenderingBuilder(adaptProducer(fragmentsProducer));
118+
static Builder fragmentsProducer(Object fragmentsProducer) {
119+
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(fragmentsProducer.getClass());
120+
Assert.isTrue(adapter != null, "Unknown producer " + fragmentsProducer.getClass());
121+
Publisher<Fragment> publisher = adapter.toPublisher(fragmentsProducer);
122+
return fragmentsPublisher(publisher);
113123
}
114124

115-
private static Publisher<Fragment> adaptProducer(Object producer) {
116-
ReactiveAdapter adapter = ReactiveAdapterRegistry.getSharedInstance().getAdapter(producer.getClass());
117-
Assert.isTrue(adapter != null, "Unknown producer " + producer.getClass());
118-
return adapter.toPublisher(producer);
125+
126+
/**
127+
* The same as {@link #fragment(String, Map)}.
128+
* @deprecated in favor of {@link #fragment(String, Map)}
129+
*/
130+
@Deprecated(since = "6.2.13", forRemoval = true)
131+
static Builder with(String viewName, Map<String, Object> model) {
132+
return fragment(viewName, model);
133+
}
134+
135+
/**
136+
* The same as {@link #fragments(Collection)}.
137+
* @deprecated in favor of {@link #fragments(Collection)}
138+
*/
139+
@Deprecated(since = "6.2.13", forRemoval = true)
140+
static Builder with(String viewName) {
141+
return fragment(viewName);
142+
}
143+
144+
/**
145+
* The same as {@link #fragments(Collection)}.
146+
* @deprecated in favor of {@link #fragments(Collection)}
147+
*/
148+
@Deprecated(since = "6.2.13", forRemoval = true)
149+
static Builder withCollection(Collection<Fragment> fragments) {
150+
return fragments(fragments);
151+
}
152+
153+
/**
154+
* The same as {@link #fragmentsPublisher(Publisher)}.
155+
* @deprecated in favor of {@link #fragmentsPublisher(Publisher)}
156+
*/
157+
@Deprecated(since = "6.2.13", forRemoval = true)
158+
static <P extends Publisher<Fragment>> Builder withPublisher(P fragmentsPublisher) {
159+
return fragmentsPublisher(fragmentsPublisher);
160+
}
161+
162+
/**
163+
* The same as {@link #fragmentsProducer(Object)}.
164+
* @deprecated in favor of {@link #fragmentsProducer(Object)}
165+
*/
166+
@Deprecated(since = "6.2.13", forRemoval = true)
167+
static Builder withProducer(Object fragmentsProducer) {
168+
return fragmentsProducer(fragmentsProducer);
119169
}
120170

121171

@@ -148,30 +198,39 @@ interface Builder {
148198
Builder headers(Consumer<HttpHeaders> headersConsumer);
149199

150200
/**
151-
* Add a fragment with a view name and a model.
152-
* @param viewName the name of the view for the fragment
153-
* @param model attributes for the fragment in addition to model
154-
* attributes inherited from the model for the request
201+
* Add an HTML fragment.
202+
* @param viewName the view name for the fragment
203+
* @param model fragment attributes in addition to attributes from the
204+
* shared model for the request
155205
* @return this builder
156206
*/
157207
Builder fragment(String viewName, Map<String, Object> model);
158208

159209
/**
160-
* Variant of {@link #fragment(String, Map)} with a view name only, where
161-
* the fragment model also inherits model attributes from the shared
210+
* Add an HTML fragment. The fragment will use attributes from the shared
162211
* model for the request.
163-
* @param viewName the name of the view for the fragment
212+
* @param viewName the view name for the fragment
164213
* @return this builder
165214
*/
166215
Builder fragment(String viewName);
167216

168217
/**
169-
* Variant of {@link #fragment(String, Map)} with a {@link Fragment}.
170-
* @param fragment the fragment to add
218+
* Add an HTML fragment.
219+
* @param fragment the fragment to add; the fragment also inherits
220+
* attributes from the shared model for the request
171221
* @return this builder
172222
*/
173223
Builder fragment(Fragment fragment);
174224

225+
/**
226+
* Add HTML fragments.
227+
* @param fragments the fragments to add; each fragment also inherits
228+
* attributes from the shared model for the request
229+
* @return this builder
230+
* @since 6.2.13
231+
*/
232+
Builder fragments(Collection<Fragment> fragments);
233+
175234
/**
176235
* Build the {@link FragmentsRendering} instance.
177236
*/

spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result)
220220
}
221221

222222
valueMono = (result.getReturnValue() != null ?
223-
Mono.just(FragmentsRendering.withPublisher(adapter.toPublisher(result.getReturnValue())).build()) :
223+
Mono.just(FragmentsRendering.fragmentsPublisher(adapter.toPublisher(result.getReturnValue())).build()) :
224224
Mono.empty());
225225

226226
valueType = ResolvableType.forClass(FragmentsRendering.class);
@@ -252,7 +252,7 @@ public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result)
252252
}
253253

254254
if (Collection.class.isAssignableFrom(clazz)) {
255-
returnValue = FragmentsRendering.withCollection((Collection<Fragment>) returnValue).build();
255+
returnValue = FragmentsRendering.fragments((Collection<Fragment>) returnValue).build();
256256
clazz = FragmentsRendering.class;
257257
}
258258

spring-webflux/src/test/java/org/springframework/web/reactive/result/view/FragmentViewResolutionResultHandlerTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ public class FragmentViewResolutionResultHandlerTests {
6666
static Stream<Arguments> arguments() {
6767
Flux<Fragment> fragmentFlux = Flux.just(fragment1, fragment2).subscribeOn(Schedulers.boundedElastic());
6868
return Stream.of(
69-
Arguments.of(FragmentsRendering.withPublisher(fragmentFlux).build(),
69+
Arguments.of(FragmentsRendering.fragmentsPublisher(fragmentFlux).build(),
7070
on(Handler.class).resolveReturnType(FragmentsRendering.class)),
71-
Arguments.of(FragmentsRendering.withCollection(List.of(fragment1, fragment2)).build(),
71+
Arguments.of(FragmentsRendering.fragments(List.of(fragment1, fragment2)).build(),
7272
on(Handler.class).resolveReturnType(FragmentsRendering.class)),
7373
Arguments.of(fragmentFlux,
7474
on(Handler.class).resolveReturnType(Flux.class, Fragment.class)),

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ModelAndViewMethodReturnValueHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void handleReturnValue(@Nullable Object returnValue, MethodParameter retu
9292
}
9393

9494
if (returnValue instanceof Collection<?> mavs) {
95-
returnValue = FragmentsRendering.with((Collection<ModelAndView>) mavs).build();
95+
returnValue = FragmentsRendering.fragments((Collection<ModelAndView>) mavs).build();
9696
}
9797

9898
if (returnValue instanceof FragmentsRendering rendering) {

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitterReturnValueHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ public void handle(ModelAndView modelAndView) throws IOException {
398398
FragmentHttpServletResponse fragmentResponse =
399399
new FragmentHttpServletResponse(this.response, this.charset);
400400

401-
FragmentsRendering render = FragmentsRendering.with(List.of(modelAndView)).build();
401+
FragmentsRendering render = FragmentsRendering.fragments(List.of(modelAndView)).build();
402402
render.resolveNestedViews(this::resolveViewName, this.locale);
403403
render.render(modelAndView.getModel(), this.request, fragmentResponse);
404404

0 commit comments

Comments
 (0)