You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by kn...@apache.org on 2009/04/11 13:16:42 UTC

svn commit: r764192 - in /wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket: ./ protocol/http/ request/handler/impl/ request/handler/impl/render/

Author: knopp
Date: Sat Apr 11 11:16:41 2009
New Revision: 764192

URL: http://svn.apache.org/viewvc?rev=764192&view=rev
Log: (empty)

Added:
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java   (with props)
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java   (with props)
Modified:
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/Application.java
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
    wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/RenderPageRequestHandler.java

Modified: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/Application.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/Application.java?rev=764192&r1=764191&r2=764192&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/Application.java (original)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/Application.java Sat Apr 11 11:16:41 2009
@@ -13,6 +13,8 @@
 import org.apache.wicket.page.persistent.PageStore;
 import org.apache.wicket.page.persistent.PersistentPageManager;
 import org.apache.wicket.page.persistent.disk.DiskDataStore;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler;
+import org.apache.wicket.request.handler.impl.render.RenderPageRequestHandlerDelegate;
 import org.apache.wicket.request.request.Request;
 import org.apache.wicket.request.response.Response;
 import org.apache.wicket.session.HttpSessionStore;
@@ -51,7 +53,7 @@
 		{
 			throw new IllegalStateException("Application name can only be set once.");
 		}
-		
+
 		this.name = name;
 		applications.put(name, this);
 	}
@@ -146,11 +148,11 @@
 	{
 		return applicationSettings;
 	}
-	
+
 	// // Request cycle
 
 	protected abstract RequestCycle newRequestCycle(Request request, Response response);
-	
+
 	public final RequestCycle createRequestCycle(Request request, Response response)
 	{
 		RequestCycle requestCycle = newRequestCycle(request, response);
@@ -162,7 +164,7 @@
 			}
 		});
 		return requestCycle;
-	}	
+	}
 
 	private static Map<String, Application> applications = new ConcurrentHashMap<String, Application>();
 
@@ -186,30 +188,30 @@
 	}
 
 	// // Session
-	
+
 	protected Session newSession(RequestCycle requestCycle)
-	{		
+	{
 		return new Session(requestCycle);
 	}
-	
+
 	Session fetchCreateAndSetSession(RequestCycle requestCycle)
 	{
 		Check.argumentNotNull(requestCycle, "requestCycle");
-						
-		Session session = getSessionStore().lookup(requestCycle.getRequest()); 
+
+		Session session = getSessionStore().lookup(requestCycle.getRequest());
 		if (session == null)
-		{			
+		{
 			session = newSession(requestCycle);
 			ThreadContext.setSession(session);
 			getPageManager().newSessionCreated();
-		}		
+		}
 		else
 		{
 			ThreadContext.setSession(session);
 		}
 		return session;
 	}
-	
+
 	// // PageManager
 
 	protected PageManager newPageManager()
@@ -229,12 +231,12 @@
 		{
 			Session.get().bind();
 		}
-		
+
 		private MetaDataKey<Object> requestCycleMetaDataKey = new MetaDataKey<Object>()
 		{
-			private static final long serialVersionUID = 1L;			
+			private static final long serialVersionUID = 1L;
 		};
-		
+
 		public Object getRequestData()
 		{
 			RequestCycle requestCycle = RequestCycle.get();
@@ -244,7 +246,7 @@
 			}
 			return requestCycle.getMetaData(requestCycleMetaDataKey);
 		}
-		
+
 		public Serializable getSessionAttribute(String key)
 		{
 			return Session.get().getAttribute(key);
@@ -264,19 +266,26 @@
 			}
 			requestCycle.setMetaData(requestCycleMetaDataKey, data);
 		}
+
 		public void setSessionAttribute(String key, Serializable value)
 		{
 			Session.get().setAttribute(key, value);
 		}
 	};
-	
+
 	public PageManager getPageManager()
 	{
 		return pageManager;
 	}
-	
+
 	protected PageManagerContext getPageManagerContext()
 	{
 		return pageManagerContext;
 	}
+
+	//
+	// Page Rendering
+	//
+	public abstract RenderPageRequestHandlerDelegate getRenderPageRequestHandlerDelegate(
+			RenderPageRequestHandler renderPageRequestHandler);
 }

Modified: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java?rev=764192&r1=764191&r2=764192&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java (original)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/protocol/http/WebApplication.java Sat Apr 11 11:16:41 2009
@@ -39,6 +39,9 @@
 import org.apache.wicket.request.encoder.EncoderContext;
 import org.apache.wicket.request.encoder.PageInstanceEncoder;
 import org.apache.wicket.request.encoder.ResourceReferenceEncoder;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler;
+import org.apache.wicket.request.handler.impl.render.RenderPageRequestHandlerDelegate;
+import org.apache.wicket.request.handler.impl.render.WebRenderPageRequestHandlerDelegate;
 import org.apache.wicket.request.request.Request;
 import org.apache.wicket.request.response.BufferedWebResponse;
 import org.apache.wicket.request.response.Response;
@@ -262,4 +265,11 @@
 	}
 	
 	private WicketFilter wicketFilter;
+	
+	@Override
+	public RenderPageRequestHandlerDelegate getRenderPageRequestHandlerDelegate(
+			RenderPageRequestHandler renderPageRequestHandler)
+	{
+		return new WebRenderPageRequestHandlerDelegate(renderPageRequestHandler);
+	}
 }

Modified: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/RenderPageRequestHandler.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/RenderPageRequestHandler.java?rev=764192&r1=764191&r2=764192&view=diff
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/RenderPageRequestHandler.java (original)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/RenderPageRequestHandler.java Sat Apr 11 11:16:41 2009
@@ -20,20 +20,12 @@
 import org.apache.wicket.IPage;
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.RequestCycle;
-import org.apache.wicket.Session;
-import org.apache.wicket.protocol.http.WebApplication;
 import org.apache.wicket.request.RequestHandler;
-import org.apache.wicket.request.Url;
 import org.apache.wicket.request.handler.PageClassRequestHandler;
 import org.apache.wicket.request.handler.PageProvider;
 import org.apache.wicket.request.handler.PageRequestHandler;
-import org.apache.wicket.request.response.BufferedWebResponse;
-import org.apache.wicket.request.response.Response;
-import org.apache.wicket.request.response.WebResponse;
-import org.apache.wicket.settings.RequestCycleSettings;
+import org.apache.wicket.request.handler.impl.render.RenderPageRequestHandlerDelegate;
 import org.apache.wicket.util.lang.Check;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * {@link RequestHandler} that renders page instance. Depending on the <code>redirectPolicy</code>
@@ -101,229 +93,39 @@
 		this.pageProvider = pageProvider;
 	}
 
-	public IPage getPage()
+	public PageProvider getPageProvider()
 	{
-		return pageProvider.getPageInstance();
+		return pageProvider;
 	}
-
-	/**
-	 * Returns the {@link RedirectPolicy}
-	 * 
-	 * @return redirect policy
-	 */
+	
 	public RedirectPolicy getRedirectPolicy()
 	{
 		return redirectPolicy;
 	}
 
-	public void detach(RequestCycle requestCycle)
-	{
-		pageProvider.detach();
-	}
-
-	private boolean isOnePassRender()
-	{
-		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER;
-	}
-
-	private boolean isRedirectToRender()
-	{
-		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.REDIRECT_TO_RENDER;
-	}
-
-	private boolean isRedirectToBuffer()
-	{
-		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.REDIRECT_TO_BUFFER;
-	}
-
-	private void renderPage()
-	{
-		getPage().renderPage();
-	}
-
-	protected String getSessionId()
-	{
-		return Session.get().getId();
-	}
-
-	protected boolean isSessionTemporary()
-	{
-		return Session.get().isTemporary();
-	}
-
-	protected BufferedWebResponse getAndRemoveBufferedResponse(Url url)
+	public Class<? extends IPage> getPageClass()
 	{
-		return WebApplication.get().getAndRemoveBufferedResponse(getSessionId(), url);
+		return pageProvider.getPageClass();		
 	}
 
-	protected void storeBufferedResponse(Url url, BufferedWebResponse response)
+	public PageParameters getPageParameters()
 	{
-		WebApplication.get().storeBufferedResponse(getSessionId(), url, response);
+		return pageProvider.getPageParameters();
 	}
-
-	/**
-	 * Renders page to a {@link BufferedWebResponse}. All URLs in page will be rendered relative to
-	 * <code>targetUrl</code>
-	 * 
-	 * @param targetUrl
-	 * @param requestCycle
-	 * @return BufferedWebResponse containing page body
-	 */
-	protected BufferedWebResponse renderPage(Url targetUrl, RequestCycle requestCycle)
+	
+	public void detach(RequestCycle requestCycle)
 	{
-		// keep the original response
-		final Response originalResponse = requestCycle.getResponse();
-
-		// buffered web response for page
-		BufferedWebResponse response = new BufferedWebResponse()
-		{
-			@Override
-			public String encodeURL(String url)
-			{
-				return originalResponse.encodeURL(url);
-			}
-		};
-
-		// keep the original base URL
-		Url originalBaseUrl = requestCycle.getUrlRenderer().setBaseUrl(targetUrl);
-
-		try
-		{
-			requestCycle.setResponse(response);
-			getPage().renderPage();
-			return response;
-		}
-		finally
-		{
-			// restore original response and base URL
-			requestCycle.setResponse(originalResponse);
-			requestCycle.getUrlRenderer().setBaseUrl(originalBaseUrl);
-		}
+		pageProvider.detach();
 	}
-
-	private void redirectTo(Url url, RequestCycle requestCycle)
+	
+	public IPage getPage()
 	{
-		WebResponse response = (WebResponse) requestCycle.getResponse();
-		String relativeUrl = requestCycle.getUrlRenderer().renderUrl(url);
-		response.sendRedirect(relativeUrl);
+		return pageProvider.getPageInstance();
 	}
-
+	
 	public void respond(RequestCycle requestCycle)
 	{
-		Url currentUrl = requestCycle.getRequest().getUrl();
-		Url targetUrl = requestCycle.urlFor(this);
-
-		//
-		// the code below is little hairy but we have to handle 3 redirect policies 
-		// and 3 rendering strategies
-		//
-		
-		// try to get an already rendered buffered response for current URL
-		BufferedWebResponse bufferedResponse = getAndRemoveBufferedResponse(currentUrl);
-
-		if (bufferedResponse != null)
-		{
-			logger.warn("The Buffered response should be handled by BufferedResponseRequestHandler");
-			// if there is saved response for this URL render it
-			bufferedResponse.writeTo((WebResponse) requestCycle.getResponse());
-		}
-		else if (redirectPolicy == RedirectPolicy.NEVER_REDIRECT || isOnePassRender() // 
-				|| (targetUrl.equals(currentUrl) && !getPage().isPageStateless()) //
-				|| (targetUrl.equals(currentUrl) && isRedirectToRender() && getPage().isPageStateless()))
-		{
-			// if the policy is never to redirect
-			// or one pass render mode is on
-			// or the targetUrl matches current url and the page is not stateless
-			// or the targetUrl matches current url, page is stateless but it's redirect-to-render
-			// just render the page
-			renderPage();
-		}
-		else if (!targetUrl.equals(currentUrl) //
-				&& (redirectPolicy == RedirectPolicy.ALWAYS_REDIRECT || isRedirectToRender()))
-		{
-			// if target URL is different
-			// and render policy is always-redirect or it's redirect-to-render
-			redirectTo(targetUrl, requestCycle);
-		}
-		else if (!targetUrl.equals(currentUrl) //
-				&& isSessionTemporary() && getPage().isPageStateless())		
-		{
-			// if target URL is different and session is temporary and page is stateless
-			// this is  special case when page is stateless but there is no session so we can't render it to buffer
-			
-			// note: if we had session here we would render the page to buffer and then redirect to URL generated 
-			// *after* page has been rendered (the statelessness may change during render). this would save one redirect
-			// because now we have to render to URL generated *before* page is rendered, render the page, get URL
-			// after render and if the URL is different (meaning page is not stateless), save the buffer and redirect again
-			// (which is pretty much what the next step does)
-			redirectTo(targetUrl, requestCycle);
-		}
-		else if (isRedirectToBuffer())
-		{
-			// redirect to buffer
-			BufferedWebResponse response = renderPage(targetUrl, requestCycle);
-
-			// check if the url hasn't changed after page has been rendered
-			// (i.e. the stateless flag might have changed which could result in different page url)
-			Url targetUrl2 = requestCycle.urlFor(this);
-
-			if (targetUrl.getSegments().equals(targetUrl2.getSegments()) == false)
-			{
-				// the amount of segments is different - generated relative URLs will not work, we
-				// need to rerender the page. This shouldn't happen, but in theory it can - with
-				// RequestHandlerEncoders that produce different URLs with different amount of
-				// segments for stateless and stateful pages
-				response = renderPage(targetUrl2, requestCycle);
-			}
-
-			// if page is still stateless after render
-			if (getPage().isPageStateless() && !enableRedirectForStatelessPage())
-			{
-				// we don't want the redirect to happen for stateless page
-				// example:
-				// when a normal mounted stateful page is hit at /mount/point
-				// wicket renders the page to buffer and redirects to /mount/point?12
-				// but for stateless page the redirect is not necessary
-				// also for listener interface on stateful page we want to redirect
-				// after the listener is invoked, but on stateless page the user
-				// must ask for redirect explicitely
-				response.writeTo((WebResponse) requestCycle.getResponse());
-			}
-			else
-			{
-				storeBufferedResponse(targetUrl2, response);
-
-				redirectTo(targetUrl2, requestCycle);
-			}
-		}
-		else
-		{
-			throw new IllegalStateException("Unknown RenderStrategy.");
-		}
-	}
-
-	/**
-	 * When the page renders to buffer and it is still stateless after rendering, this flag
-	 * determines whether the redirect will take place or not.
-	 * <p>
-	 * Normally there is no reason for a stateless page to redirect
-	 * 
-	 * @return boolean value
-	 */
-	protected boolean enableRedirectForStatelessPage()
-	{
-		return false;
+		RenderPageRequestHandlerDelegate delegate = Application.get().getRenderPageRequestHandlerDelegate(this);
+		delegate.respond(requestCycle);
 	}
-
-	public Class<? extends IPage> getPageClass()
-	{
-		return pageProvider.getPageClass();		
-	}
-
-	public PageParameters getPageParameters()
-	{
-		return pageProvider.getPageParameters();
-	}
-
-	private static Logger logger = LoggerFactory.getLogger(RenderPageRequestHandler.class);
 }

Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java?rev=764192&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java Sat Apr 11 11:16:41 2009
@@ -0,0 +1,40 @@
+package org.apache.wicket.request.handler.impl.render;
+
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.request.handler.PageProvider;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler.RedirectPolicy;
+
+/**
+ * Delegate responsible for rendering the page. Depending on the implementation (web, test, portlet,
+ * etc.) the delegate may or may not support the redirect policy set in the
+ * {@link RenderPageRequestHandler}.
+ * 
+ * @author Matej Knopp
+ */
+public abstract class RenderPageRequestHandlerDelegate
+{
+	private final RenderPageRequestHandler renderPageRequestHandler;
+
+	public RenderPageRequestHandlerDelegate(RenderPageRequestHandler renderPageRequestHandler)
+	{
+		this.renderPageRequestHandler = renderPageRequestHandler;
+	}
+
+	public PageProvider getPageProvider()
+	{
+		return renderPageRequestHandler.getPageProvider();
+	}
+
+	public RedirectPolicy getRedirectPolicy()
+	{
+		return renderPageRequestHandler.getRedirectPolicy();
+	}
+
+	public RenderPageRequestHandler getRenderPageRequestHandler()
+	{
+		return renderPageRequestHandler;
+	}
+
+	public abstract void respond(RequestCycle requestCycle);
+}

Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/RenderPageRequestHandlerDelegate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java
URL: http://svn.apache.org/viewvc/wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java?rev=764192&view=auto
==============================================================================
--- wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java (added)
+++ wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java Sat Apr 11 11:16:41 2009
@@ -0,0 +1,226 @@
+package org.apache.wicket.request.handler.impl.render;
+
+import org.apache.wicket.Application;
+import org.apache.wicket.IPage;
+import org.apache.wicket.RequestCycle;
+import org.apache.wicket.Session;
+import org.apache.wicket.protocol.http.WebApplication;
+import org.apache.wicket.request.Url;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler;
+import org.apache.wicket.request.handler.impl.RenderPageRequestHandler.RedirectPolicy;
+import org.apache.wicket.request.response.BufferedWebResponse;
+import org.apache.wicket.request.response.Response;
+import org.apache.wicket.request.response.WebResponse;
+import org.apache.wicket.settings.RequestCycleSettings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class WebRenderPageRequestHandlerDelegate extends RenderPageRequestHandlerDelegate
+{
+
+	public WebRenderPageRequestHandlerDelegate(RenderPageRequestHandler renderPageRequestHandler)
+	{
+		super(renderPageRequestHandler);
+	}
+
+	public IPage getPage()
+	{
+		return getPageProvider().getPageInstance();
+	}
+
+	private boolean isOnePassRender()
+	{
+		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.ONE_PASS_RENDER;
+	}
+
+	private boolean isRedirectToRender()
+	{
+		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.REDIRECT_TO_RENDER;
+	}
+
+	private boolean isRedirectToBuffer()
+	{
+		return Application.get().getRequestCycleSettings().getRenderStrategy() == RequestCycleSettings.RenderStrategy.REDIRECT_TO_BUFFER;
+	}
+
+	private void renderPage()
+	{
+		getPage().renderPage();
+	}
+
+	protected String getSessionId()
+	{
+		return Session.get().getId();
+	}
+
+	protected boolean isSessionTemporary()
+	{
+		return Session.get().isTemporary();
+	}
+
+	protected BufferedWebResponse getAndRemoveBufferedResponse(Url url)
+	{
+		return WebApplication.get().getAndRemoveBufferedResponse(getSessionId(), url);
+	}
+
+	protected void storeBufferedResponse(Url url, BufferedWebResponse response)
+	{
+		WebApplication.get().storeBufferedResponse(getSessionId(), url, response);
+	}
+
+	/**
+	 * Renders page to a {@link BufferedWebResponse}. All URLs in page will be rendered relative to
+	 * <code>targetUrl</code>
+	 * 
+	 * @param targetUrl
+	 * @param requestCycle
+	 * @return BufferedWebResponse containing page body
+	 */
+	protected BufferedWebResponse renderPage(Url targetUrl, RequestCycle requestCycle)
+	{
+		// keep the original response
+		final Response originalResponse = requestCycle.getResponse();
+
+		// buffered web response for page
+		BufferedWebResponse response = new BufferedWebResponse()
+		{
+			@Override
+			public String encodeURL(String url)
+			{
+				return originalResponse.encodeURL(url);
+			}
+		};
+
+		// keep the original base URL
+		Url originalBaseUrl = requestCycle.getUrlRenderer().setBaseUrl(targetUrl);
+
+		try
+		{
+			requestCycle.setResponse(response);
+			getPage().renderPage();
+			return response;
+		}
+		finally
+		{
+			// restore original response and base URL
+			requestCycle.setResponse(originalResponse);
+			requestCycle.getUrlRenderer().setBaseUrl(originalBaseUrl);
+		}
+	}
+
+	private void redirectTo(Url url, RequestCycle requestCycle)
+	{
+		WebResponse response = (WebResponse) requestCycle.getResponse();
+		String relativeUrl = requestCycle.getUrlRenderer().renderUrl(url);
+		response.sendRedirect(relativeUrl);
+	}
+
+	public void respond(RequestCycle requestCycle)
+	{
+		Url currentUrl = requestCycle.getRequest().getUrl();
+		Url targetUrl = requestCycle.urlFor(getRenderPageRequestHandler());
+
+		//
+		// the code below is little hairy but we have to handle 3 redirect policies 
+		// and 3 rendering strategies
+		//
+		
+		// try to get an already rendered buffered response for current URL
+		BufferedWebResponse bufferedResponse = getAndRemoveBufferedResponse(currentUrl);
+
+		if (bufferedResponse != null)
+		{
+			logger.warn("The Buffered response should be handled by BufferedResponseRequestHandler");
+			// if there is saved response for this URL render it
+			bufferedResponse.writeTo((WebResponse) requestCycle.getResponse());
+		}
+		else if (getRedirectPolicy() == RedirectPolicy.NEVER_REDIRECT || isOnePassRender() // 
+				|| (targetUrl.equals(currentUrl) && !getPage().isPageStateless()) //
+				|| (targetUrl.equals(currentUrl) && isRedirectToRender() && getPage().isPageStateless()))
+		{
+			// if the policy is never to redirect
+			// or one pass render mode is on
+			// or the targetUrl matches current url and the page is not stateless
+			// or the targetUrl matches current url, page is stateless but it's redirect-to-render
+			// just render the page
+			renderPage();
+		}
+		else if (!targetUrl.equals(currentUrl) //
+				&& (getRedirectPolicy() == RedirectPolicy.ALWAYS_REDIRECT || isRedirectToRender()))
+		{
+			// if target URL is different
+			// and render policy is always-redirect or it's redirect-to-render
+			redirectTo(targetUrl, requestCycle);
+		}
+		else if (!targetUrl.equals(currentUrl) //
+				&& isSessionTemporary() && getPage().isPageStateless())		
+		{
+			// if target URL is different and session is temporary and page is stateless
+			// this is  special case when page is stateless but there is no session so we can't render it to buffer
+			
+			// note: if we had session here we would render the page to buffer and then redirect to URL generated 
+			// *after* page has been rendered (the statelessness may change during render). this would save one redirect
+			// because now we have to render to URL generated *before* page is rendered, render the page, get URL
+			// after render and if the URL is different (meaning page is not stateless), save the buffer and redirect again
+			// (which is pretty much what the next step does)
+			redirectTo(targetUrl, requestCycle);
+		}
+		else if (isRedirectToBuffer())
+		{
+			// redirect to buffer
+			BufferedWebResponse response = renderPage(targetUrl, requestCycle);
+
+			// check if the url hasn't changed after page has been rendered
+			// (i.e. the stateless flag might have changed which could result in different page url)
+			Url targetUrl2 = requestCycle.urlFor(this.getRenderPageRequestHandler());
+
+			if (targetUrl.getSegments().equals(targetUrl2.getSegments()) == false)
+			{
+				// the amount of segments is different - generated relative URLs will not work, we
+				// need to rerender the page. This shouldn't happen, but in theory it can - with
+				// RequestHandlerEncoders that produce different URLs with different amount of
+				// segments for stateless and stateful pages
+				response = renderPage(targetUrl2, requestCycle);
+			}
+
+			// if page is still stateless after render
+			if (getPage().isPageStateless() && !enableRedirectForStatelessPage())
+			{
+				// we don't want the redirect to happen for stateless page
+				// example:
+				// when a normal mounted stateful page is hit at /mount/point
+				// wicket renders the page to buffer and redirects to /mount/point?12
+				// but for stateless page the redirect is not necessary
+				// also for listener interface on stateful page we want to redirect
+				// after the listener is invoked, but on stateless page the user
+				// must ask for redirect explicitely
+				response.writeTo((WebResponse) requestCycle.getResponse());
+			}
+			else
+			{
+				storeBufferedResponse(targetUrl2, response);
+
+				redirectTo(targetUrl2, requestCycle);
+			}
+		}
+		else
+		{
+			throw new IllegalStateException("Unknown RenderStrategy.");
+		}
+	}
+
+	/**
+	 * When the page renders to buffer and it is still stateless after rendering, this flag
+	 * determines whether the redirect will take place or not.
+	 * <p>
+	 * Normally there is no reason for a stateless page to redirect
+	 * 
+	 * @return boolean value
+	 */
+	protected boolean enableRedirectForStatelessPage()
+	{
+		return false;
+	}
+
+	private static Logger logger = LoggerFactory.getLogger(WebRenderPageRequestHandlerDelegate.class);
+}

Propchange: wicket/sandbox/knopp/experimental/wicket-ng/src/main/java/org/apache/wicket/request/handler/impl/render/WebRenderPageRequestHandlerDelegate.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain