001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.web.reactive.function.server;
018
019import java.util.Collection;
020import java.util.Map;
021import java.util.function.Consumer;
022
023import reactor.core.publisher.Mono;
024
025import org.springframework.http.HttpHeaders;
026import org.springframework.http.HttpStatus;
027import org.springframework.http.ResponseCookie;
028import org.springframework.lang.Nullable;
029import org.springframework.util.MultiValueMap;
030
031/**
032 * Rendering-specific subtype of {@link ServerResponse} that exposes model and template data.
033 *
034 * @author Arjen Poutsma
035 * @author Juergen Hoeller
036 * @since 5.0
037 */
038public interface RenderingResponse extends ServerResponse {
039
040        /**
041         * Return the name of the template to be rendered.
042         */
043        String name();
044
045        /**
046         * Return the unmodifiable model map.
047         */
048        Map<String, Object> model();
049
050
051        // Builder
052
053        /**
054         * Create a builder with the template name, status code, headers and model of the given response.
055         * @param other the response to copy the values from
056         * @return the created builder
057         */
058        static Builder from(RenderingResponse other) {
059                return new DefaultRenderingResponseBuilder(other);
060        }
061
062        /**
063         * Create a builder with the given template name.
064         * @param name the name of the template to render
065         * @return the created builder
066         */
067        static Builder create(String name) {
068                return new DefaultRenderingResponseBuilder(name);
069        }
070
071
072        /**
073         * Defines a builder for {@code RenderingResponse}.
074         */
075        interface Builder {
076
077                /**
078                 * Add the supplied attribute to the model using a
079                 * {@linkplain org.springframework.core.Conventions#getVariableName generated name}.
080                 * <p><em>Note: Empty {@link Collection Collections} are not added to
081                 * the model when using this method because we cannot correctly determine
082                 * the true convention name. View code should check for {@code null} rather
083                 * than for empty collections.</em>
084                 * @param attribute the model attribute value (never {@code null})
085                 */
086                Builder modelAttribute(Object attribute);
087
088                /**
089                 * Add the supplied attribute value under the supplied name.
090                 * @param name the name of the model attribute (never {@code null})
091                 * @param value the model attribute value (can be {@code null})
092                 */
093                Builder modelAttribute(String name, @Nullable Object value);
094
095                /**
096                 * Copy all attributes in the supplied array into the model,
097                 * using attribute name generation for each element.
098                 * @see #modelAttribute(Object)
099                 */
100                Builder modelAttributes(Object... attributes);
101
102                /**
103                 * Copy all attributes in the supplied {@code Collection} into the model,
104                 * using attribute name generation for each element.
105                 * @see #modelAttribute(Object)
106                 */
107                Builder modelAttributes(Collection<?> attributes);
108
109                /**
110                 * Copy all attributes in the supplied {@code Map} into the model.
111                 * @see #modelAttribute(String, Object)
112                 */
113                Builder modelAttributes(Map<String, ?> attributes);
114
115                /**
116                 * Add the given header value(s) under the given name.
117                 * @param headerName the header name
118                 * @param headerValues the header value(s)
119                 * @return this builder
120                 * @see HttpHeaders#add(String, String)
121                 */
122                Builder header(String headerName, String... headerValues);
123
124                /**
125                 * Copy the given headers into the entity's headers map.
126                 * @param headers the existing HttpHeaders to copy from
127                 * @return this builder
128                 * @see HttpHeaders#add(String, String)
129                 */
130                Builder headers(HttpHeaders headers);
131
132                /**
133                 * Set the HTTP status.
134                 * @param status the response status
135                 * @return this builder
136                 */
137                Builder status(HttpStatus status);
138
139                /**
140                 * Set the HTTP status.
141                 * @param status the response status
142                 * @return this builder
143                 * @since 5.0.3
144                 */
145                Builder status(int status);
146
147                /**
148                 * Add the given cookie to the response.
149                 * @param cookie the cookie to add
150                 * @return this builder
151                 */
152                Builder cookie(ResponseCookie cookie);
153
154                /**
155                 * Manipulate this response's cookies with the given consumer. The
156                 * cookies provided to the consumer are "live", so that the consumer can be used to
157                 * {@linkplain MultiValueMap#set(Object, Object) overwrite} existing cookies,
158                 * {@linkplain MultiValueMap#remove(Object) remove} cookies, or use any of the other
159                 * {@link MultiValueMap} methods.
160                 * @param cookiesConsumer a function that consumes the cookies
161                 * @return this builder
162                 */
163                Builder cookies(Consumer<MultiValueMap<String, ResponseCookie>> cookiesConsumer);
164
165                /**
166                 * Build the response.
167                 * @return the built response
168                 */
169                Mono<RenderingResponse> build();
170        }
171
172}