package fr.openwide.core.wicket.request.mapper;
import org.apache.wicket.Application;
import org.apache.wicket.core.request.handler.PageProvider;
import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
import org.apache.wicket.core.request.mapper.MountedMapper;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.component.IRequestablePage;
import org.apache.wicket.request.mapper.info.PageInfo;
import org.apache.wicket.request.mapper.parameter.IPageParametersEncoder;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.IProvider;
/**
* This class comes from: https://github.com/unterstein/wicket-tales/
*
* This mapper represents exactly the same behavior like the default
* {@link MountedMapper}, except one behavior:<br/>
* The default {@link MountedMapper} implementation prefers the pageId parameter
* with a higher priority then the rest of the {@link PageParameters}.<br>
* This preference leads to the following behavior:
*
* <pre>
* ...myApplication/User/4?15
* </pre>
*
* leads to the UserPage with the indexed {@link PageParameters} "4" at index 0.
* So the User with id 4 is shown. When a user manually changes the URL to
* something like this:
*
* <pre>
* ...myApplication/User/5?15
* </pre>
*
* The {@link MountedMapper} would deliver the same page as before and would
* show the user with id 4 and not - like it is implicated in the url - the user
* with id 5, because the pageId parameter is preferred during mapping process. <br/>
* <br/>
* Therefore this implementation compares the existing {@link PageParameters} of
* the cached page and the {@link PageParameters} of the current request. If a
* difference between this two {@link PageParameters} are recognized, this
* mapper redirects to a fresh bookmarkable instance of the current requested
* page. <br/>
* <br/>
* To use this mapper to mount your pages, you must declare the mapper
* programmatically in your {@link Application} by overwriting the
* "public void init()" method, like shown below:
*
* <pre>
* @Override
* public void init() {
* super.init();
* // Use our own mapper to mount the mountpage
* mount(new PageParameterAwareMountedMapper("Home", HomePage.class));
* }
* </pre>
*
* @author <a href="mailto:unterstein@me.com">Johannes Unterstein</a>
*
*/
public class PageParameterAwareMountedMapper extends MountedMapper {
public PageParameterAwareMountedMapper(String mountPath, Class<? extends IRequestablePage> pageClass,
IPageParametersEncoder pageParametersEncoder) {
super(mountPath, pageClass, pageParametersEncoder);
}
public PageParameterAwareMountedMapper(String mountPath, Class<? extends IRequestablePage> pageClass) {
super(mountPath, pageClass);
}
public PageParameterAwareMountedMapper(String mountPath,
IProvider<Class<? extends IRequestablePage>> pageClassProvider, IPageParametersEncoder pageParametersEncoder) {
super(mountPath, pageClassProvider, pageParametersEncoder);
}
public PageParameterAwareMountedMapper(String mountPath,
IProvider<Class<? extends IRequestablePage>> pageClassProvider) {
super(mountPath, pageClassProvider);
}
@Override
protected IRequestHandler processHybrid(PageInfo pageInfo, Class<? extends IRequestablePage> pageClass,
PageParameters pageParameters, Integer renderCount) {
IRequestHandler handler = super.processHybrid(pageInfo, pageClass, pageParameters, renderCount);
if (handler instanceof RenderPageRequestHandler) {
// in the current implementation (wicket 1.5.6) super.processHybrid
// returns a RenderPageRequestHandler
RenderPageRequestHandler renderPageHandler = (RenderPageRequestHandler) handler;
if (renderPageHandler.getPageProvider() instanceof PageProvider) {
PageProvider provider = (PageProvider) renderPageHandler.getPageProvider();
// This check is necessary to prevent a
// RestartResponseAtInterceptPageException at the wrong time in
// request cycle
if (provider.hasPageInstance()) {
PageParameters newPageParameters = renderPageHandler.getPageParameters();
PageParameters oldPageParameters = renderPageHandler.getPageProvider().getPageInstance()
.getPageParameters();
// if we recognize a change between the page parameter of
// the loaded
// page and the page parameter of the current request, we
// redirect
// to a fresh bookmarkable instance of that page.
if (!PageParameters.equals(oldPageParameters, newPageParameters)) {
handler = processBookmarkable(pageClass, newPageParameters);
}
}
}
}
return handler;
}
}