001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.core.request.handler;
018
019import org.apache.wicket.Application;
020import org.apache.wicket.Session;
021import org.apache.wicket.core.request.handler.logger.PageLogData;
022import org.apache.wicket.request.ILoggableRequestHandler;
023import org.apache.wicket.request.IRequestCycle;
024import org.apache.wicket.request.IRequestHandler;
025import org.apache.wicket.request.component.IRequestablePage;
026import org.apache.wicket.request.cycle.RequestCycle;
027import org.apache.wicket.request.handler.render.PageRenderer;
028import org.apache.wicket.request.mapper.parameter.PageParameters;
029import org.apache.wicket.util.lang.Args;
030
031/**
032 * {@link IRequestHandler} that renders page instance. Depending on the <code>redirectPolicy</code>
033 * flag and current request strategy the handler either just renders the page to the response, or
034 * redirects to render the page. <code>REDIRECT_TO_BUFFER</code> strategy is also supported.
035 * <p>
036 *
037 * @author Matej Knopp
038 */
039public class RenderPageRequestHandler
040        implements
041                IPageRequestHandler,
042                IPageClassRequestHandler,
043                ILoggableRequestHandler
044{
045        private final IPageProvider pageProvider;
046
047        private final RedirectPolicy redirectPolicy;
048
049        private PageLogData logData;
050
051        /**
052         * Determines whether Wicket does a redirect when rendering a page
053         *
054         * @author Matej Knopp
055         */
056        public enum RedirectPolicy {
057                /**
058                 * Always redirect if current request URL is different than page URL.
059                 */
060                ALWAYS_REDIRECT,
061
062                /**
063                 * Never redirect - always render the page to current response.
064                 */
065                NEVER_REDIRECT,
066
067                /**
068                 * Redirect if necessary. The redirect will happen when all of the following conditions are
069                 * met:
070                 * <ul>
071                 * <li>current request URL is different than page URL
072                 * <li>page is not stateless or (page is stateless and session is not temporary)
073                 * <li>render strategy is either REDIRECT_TO_BUFFER or REDIRECT_TO_RENDER
074                 * </ul>
075                 */
076                AUTO_REDIRECT
077        }
078
079        /**
080         * Constructor.
081         *
082         * @param pageClass The class of the page to render
083         */
084        public RenderPageRequestHandler(final Class<? extends IRequestablePage> pageClass)
085        {
086                this(pageClass, null);
087        }
088
089        /**
090         * Constructor.
091         *
092         * @param pageClass The class of the page to render
093         * @param parameters Wrapped query string parameters.
094         */
095        public RenderPageRequestHandler(final Class<? extends IRequestablePage> pageClass, final PageParameters parameters)
096        {
097                this(new PageProvider(pageClass, parameters));
098        }
099
100        /**
101         * Constructor.
102         *
103         * @param page The page to render
104         */
105        public RenderPageRequestHandler(final IRequestablePage page)
106        {
107                this(new PageProvider(page));
108        }
109
110        /**
111         * Construct. Renders the page with a redirect if necessary.
112         *
113         * @param pageProvider
114         */
115        public RenderPageRequestHandler(IPageProvider pageProvider)
116        {
117                this(pageProvider, RedirectPolicy.AUTO_REDIRECT);
118        }
119
120        /**
121         * Construct.
122         *
123         * @param pageProvider
124         * @param redirectPolicy
125         */
126        public RenderPageRequestHandler(IPageProvider pageProvider, RedirectPolicy redirectPolicy)
127        {
128                Args.notNull(pageProvider, "pageProvider");
129                Args.notNull(redirectPolicy, "redirectPolicy");
130
131                this.redirectPolicy = redirectPolicy;
132                this.pageProvider = pageProvider;
133
134                if (pageProvider.hasPageInstance())
135                {
136                        if (Session.exists())
137                        {
138                                // WICKET-5499
139                                Session.get().getPageManager().touchPage(pageProvider.getPageInstance());
140                        }
141                }
142        }
143
144        /**
145         * @return page provider
146         */
147        public IPageProvider getPageProvider()
148        {
149                return pageProvider;
150        }
151
152        /**
153         * @return redirect policy
154         */
155        public RedirectPolicy getRedirectPolicy()
156        {
157                return redirectPolicy;
158        }
159
160        @Override
161        public Class<? extends IRequestablePage> getPageClass()
162        {
163                return pageProvider.getPageClass();
164        }
165
166        @Override
167        public Integer getPageId()
168        {
169                return pageProvider.getPageId();
170        }
171
172        @Override
173        public PageParameters getPageParameters()
174        {
175                return pageProvider.getPageParameters();
176        }
177
178        @Override
179        public void detach(IRequestCycle requestCycle)
180        {
181                if (logData == null)
182                        logData = new PageLogData(pageProvider);
183                pageProvider.detach();
184        }
185
186        @Override
187        public PageLogData getLogData()
188        {
189                return logData;
190        }
191
192        @Override
193        public IRequestablePage getPage()
194        {
195                return pageProvider.getPageInstance();
196        }
197
198        @Override
199        public void respond(IRequestCycle requestCycle)
200        {
201                PageRenderer renderer = Application.get().getPageRendererProvider().apply(this);
202                renderer.respond((RequestCycle)requestCycle);
203        }
204
205        @Override
206        public final boolean isPageInstanceCreated()
207        {
208                return pageProvider.hasPageInstance();
209        }
210
211        @Override
212        public final Integer getRenderCount()
213        {
214                return pageProvider.getRenderCount();
215        }
216}