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;
018
019import javax.servlet.http.HttpServletResponse;
020
021import org.apache.wicket.core.request.handler.PageProvider;
022import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
023import org.apache.wicket.protocol.http.IMetaDataBufferingWebResponse;
024import org.apache.wicket.request.IRequestHandler;
025import org.apache.wicket.request.RequestHandlerExecutor;
026import org.apache.wicket.request.Response;
027import org.apache.wicket.request.cycle.RequestCycle;
028import org.apache.wicket.request.http.WebResponse;
029import org.apache.wicket.request.http.handler.RedirectRequestHandler;
030import org.apache.wicket.request.mapper.parameter.PageParameters;
031
032/**
033 * Causes Wicket to interrupt current request processing and immediately respond with the specified
034 * page. Does not reset the header meta data (e.g. cookies).
035 *
036 * @see RestartResponseException
037 */
038public class NonResettingRestartException extends RequestHandlerExecutor.ReplaceHandlerException
039{
040        private static final long serialVersionUID = 1L;
041
042        /**
043         * Constructor.
044         *
045         * @param pageClass
046         *      the class of the new page that should be rendered
047         */
048        public NonResettingRestartException(final Class<? extends Page> pageClass)
049        {
050                this(pageClass, null);
051        }
052
053        /**
054         * Constructor.
055         *
056         * @param pageClass
057         *      the class of the new page that should be rendered
058         * @param params
059         *      the page parameters to use for the new page
060         */
061        public NonResettingRestartException(final Class<? extends Page> pageClass, final PageParameters params)
062        {
063                this(pageClass, params, RenderPageRequestHandler.RedirectPolicy.AUTO_REDIRECT);
064        }
065
066        /**
067         * Constructor.
068         *
069         * @param pageClass
070         *      the class of the new page that should be rendered
071         * @param params
072         *      the page parameters to use for the new page
073         * @param redirectPolicy
074         *      the policy that mandates whether to do a redirect
075         */
076        public NonResettingRestartException(final Class<? extends Page> pageClass,
077                final PageParameters params, RenderPageRequestHandler.RedirectPolicy redirectPolicy)
078        {
079                this(createRequestHandler(pageClass, params, redirectPolicy), true);
080        }
081
082        /**
083         * Constructor.
084         *
085         * @param redirectUrl
086         *      URL to redirect to.
087         */
088        public NonResettingRestartException(final String redirectUrl)
089        {
090                this(createUrlRequestHandler(redirectUrl), true);
091        }
092
093        /**
094         * Constructor.
095         *
096         * @param handler
097         *      the IRequestHandler to use
098         * @param removeAll
099         *      a flag indicating whether to remove already a scheduled IRequestHandlers
100         */
101        public NonResettingRestartException(final IRequestHandler handler, boolean removeAll)
102        {
103                super(handler, removeAll);
104
105                transferResponseMetaData();
106        }
107
108        private void transferResponseMetaData()
109        {
110                RequestCycle cycle = RequestCycle.get();
111                Response response = cycle.getResponse();
112                if (response instanceof IMetaDataBufferingWebResponse)
113                {
114                        WebResponse originalResponse = (WebResponse) cycle.getOriginalResponse();
115                        if (originalResponse != response)
116                        {
117                                IMetaDataBufferingWebResponse bufferingWebResponse = (IMetaDataBufferingWebResponse) response;
118                                bufferingWebResponse.writeMetaData(originalResponse);
119                        }
120                }
121        }
122
123        private static IRequestHandler createRequestHandler(Class<? extends Page> pageClass, PageParameters params,
124                        RenderPageRequestHandler.RedirectPolicy redirectPolicy)
125        {
126                return new RenderPageRequestHandler(new PageProvider(pageClass, params), redirectPolicy);
127        }
128
129        private static IRequestHandler createUrlRequestHandler(final String redirectUrl)
130        {
131                return new RedirectRequestHandler(redirectUrl, HttpServletResponse.SC_MOVED_TEMPORARILY);
132        }
133}