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.result.view;
018
019import java.util.Collection;
020import java.util.Map;
021
022import org.springframework.http.HttpHeaders;
023import org.springframework.http.HttpStatus;
024import org.springframework.lang.Nullable;
025import org.springframework.ui.Model;
026
027/**
028 * Public API for HTML rendering. Supported as a return value in Spring WebFlux
029 * controllers. Comparable to the use of {@code ModelAndView} as a return value
030 * in Spring MVC controllers.
031 *
032 * <p>Controllers typically return a {@link String} view name and rely on the
033 * "implicit" model which can also be injected into the controller method.
034 * Or controllers may return model attribute(s) and rely on a default view name
035 * being selected based on the request path.
036 *
037 * <p>{@link Rendering} can be used to combine a view name with model attributes,
038 * set the HTTP status or headers, and for other more advanced options around
039 * redirect scenarios.
040 *
041 * @author Rossen Stoyanchev
042 * @since 5.0
043 */
044public interface Rendering {
045
046        /**
047         * Return the selected {@link String} view name or {@link View} object.
048         */
049        @Nullable
050        Object view();
051
052        /**
053         * Return attributes to add to the model.
054         */
055        Map<String, Object> modelAttributes();
056
057        /**
058         * Return the HTTP status to set the response to.
059         */
060        @Nullable
061        HttpStatus status();
062
063        /**
064         * Return headers to add to the response.
065         */
066        HttpHeaders headers();
067
068
069        /**
070         * Create a new builder for response rendering based on the given view name.
071         * @param name the view name to be resolved to a {@link View}
072         * @return the builder
073         */
074        static Builder<?> view(String name) {
075                return new DefaultRenderingBuilder(name);
076        }
077
078        /**
079         * Create a new builder for a redirect through a {@link RedirectView}.
080         * @param url the redirect URL
081         * @return the builder
082         */
083        static RedirectBuilder redirectTo(String url) {
084                return new DefaultRenderingBuilder(new RedirectView(url));
085        }
086
087
088        /**
089         * Defines a builder for {@link Rendering}.
090         *
091         * @param <B> a self reference to the builder type
092         */
093        interface Builder<B extends Builder<B>> {
094
095                /**
096                 * Add the given model attribute with the supplied name.
097                 * @see Model#addAttribute(String, Object)
098                 */
099                B modelAttribute(String name, Object value);
100
101                /**
102                 * Add an attribute to the model using a
103                 * {@link org.springframework.core.Conventions#getVariableName generated name}.
104                 * @see Model#addAttribute(Object)
105                 */
106                B modelAttribute(Object value);
107
108                /**
109                 * Add all given attributes to the model using
110                 * {@link org.springframework.core.Conventions#getVariableName generated names}.
111                 * @see Model#addAllAttributes(Collection)
112                 */
113                B modelAttributes(Object... values);
114
115                /**
116                 * Add the given attributes to the model.
117                 * @see Model#addAllAttributes(Map)
118                 */
119                B model(Map<String, ?> map);
120
121                /**
122                 * Specify the status to use for the response.
123                 */
124                B status(HttpStatus status);
125
126                /**
127                 * Specify a header to add to the response.
128                 */
129                B header(String headerName, String... headerValues);
130
131                /**
132                 * Specify headers to add to the response.
133                 */
134                B headers(HttpHeaders headers);
135
136                /**
137                 * Builder the {@link Rendering} instance.
138                 */
139                Rendering build();
140        }
141
142
143        /**
144         * Extends {@link Builder} with extra options for redirect scenarios.
145         */
146        interface RedirectBuilder extends Builder<RedirectBuilder> {
147
148                /**
149                 * Whether to the provided redirect URL should be prepended with the
150                 * application context path (if any).
151                 * <p>By default this is set to {@code true}.
152                 *
153                 * @see RedirectView#setContextRelative(boolean)
154                 */
155                RedirectBuilder contextRelative(boolean contextRelative);
156
157                /**
158                 * Whether to append the query string of the current URL to the target
159                 * redirect URL or not.
160                 * <p>By default this is set to {@code false}.
161                 *
162                 * @see RedirectView#setPropagateQuery(boolean)
163                 */
164                RedirectBuilder propagateQuery(boolean propagate);
165        }
166
167}