001/*
002 * Copyright 2002-2019 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.servlet.function;
018
019import java.util.Collection;
020import java.util.Map;
021import java.util.function.Consumer;
022
023import javax.servlet.http.Cookie;
024
025import org.springframework.http.HttpHeaders;
026import org.springframework.http.HttpStatus;
027import org.springframework.lang.Nullable;
028import org.springframework.util.MultiValueMap;
029
030/**
031 * Rendering-specific subtype of {@link ServerResponse} that exposes model and template data.
032 *
033 * @author Arjen Poutsma
034 * @since 5.2
035 */
036public interface RenderingResponse extends ServerResponse {
037
038        /**
039         * Return the name of the template to be rendered.
040         */
041        String name();
042
043        /**
044         * Return the unmodifiable model map.
045         */
046        Map<String, Object> model();
047
048
049        // Builder
050
051        /**
052         * Create a builder with the template name, status code, headers and model of the given response.
053         * @param other the response to copy the values from
054         * @return the created builder
055         */
056        static Builder from(RenderingResponse other) {
057                return new DefaultRenderingResponseBuilder(other);
058        }
059
060        /**
061         * Create a builder with the given template name.
062         * @param name the name of the template to render
063         * @return the created builder
064         */
065        static Builder create(String name) {
066                return new DefaultRenderingResponseBuilder(name);
067        }
068
069
070        /**
071         * Defines a builder for {@code RenderingResponse}.
072         */
073        interface Builder {
074
075                /**
076                 * Add the supplied attribute to the model using a
077                 * {@linkplain org.springframework.core.Conventions#getVariableName generated name}.
078                 * <p><em>Note: Empty {@link Collection Collections} are not added to
079                 * the model when using this method because we cannot correctly determine
080                 * the true convention name. View code should check for {@code null} rather
081                 * than for empty collections.</em>
082                 * @param attribute the model attribute value (never {@code null})
083                 */
084                Builder modelAttribute(Object attribute);
085
086                /**
087                 * Add the supplied attribute value under the supplied name.
088                 * @param name the name of the model attribute (never {@code null})
089                 * @param value the model attribute value (can be {@code null})
090                 */
091                Builder modelAttribute(String name, @Nullable Object value);
092
093                /**
094                 * Copy all attributes in the supplied array into the model,
095                 * using attribute name generation for each element.
096                 * @see #modelAttribute(Object)
097                 */
098                Builder modelAttributes(Object... attributes);
099
100                /**
101                 * Copy all attributes in the supplied {@code Collection} into the model,
102                 * using attribute name generation for each element.
103                 * @see #modelAttribute(Object)
104                 */
105                Builder modelAttributes(Collection<?> attributes);
106
107                /**
108                 * Copy all attributes in the supplied {@code Map} into the model.
109                 * @see #modelAttribute(String, Object)
110                 */
111                Builder modelAttributes(Map<String, ?> attributes);
112
113                /**
114                 * Add the given header value(s) under the given name.
115                 * @param headerName the header name
116                 * @param headerValues the header value(s)
117                 * @return this builder
118                 * @see HttpHeaders#add(String, String)
119                 */
120                Builder header(String headerName, String... headerValues);
121
122                /**
123                 * Manipulate this response's headers with the given consumer. The
124                 * headers provided to the consumer are "live", so that the consumer can be used to
125                 * {@linkplain HttpHeaders#set(String, String) overwrite} existing header values,
126                 * {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other
127                 * {@link HttpHeaders} methods.
128                 * @param headersConsumer a function that consumes the {@code HttpHeaders}
129                 * @return this builder
130                 */
131                Builder headers(Consumer<HttpHeaders> headersConsumer);
132
133                /**
134                 * Set the HTTP status.
135                 * @param status the response status
136                 * @return this builder
137                 */
138                Builder status(HttpStatus status);
139
140                /**
141                 * Set the HTTP status.
142                 * @param status the response status
143                 * @return this builder
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(Cookie 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, Cookie>> cookiesConsumer);
164
165                /**
166                 * Build the response.
167                 * @return the built response
168                 */
169                RenderingResponse build();
170        }
171
172}