package org.nocket.listener;
import gengui.util.SevereGUIException;
import java.lang.reflect.Constructor;
import org.apache.wicket.core.request.handler.PageProvider;
import org.apache.wicket.core.request.handler.RenderPageRequestHandler;
import org.apache.wicket.core.request.mapper.StalePageException;
import org.apache.wicket.protocol.http.PageExpiredException;
import org.apache.wicket.protocol.http.servlet.ResponseIOException;
import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.cycle.AbstractRequestCycleListener;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.http.WebRequest;
import org.apache.wicket.settings.IExceptionSettings;
import org.nocket.NocketWebApplication;
import org.nocket.page.DMDWebPage;
import org.nocket.page.error.DMDInternalErrorPage;
public class DMDLoggingRequestCycleListener extends AbstractRequestCycleListener {
protected Class<? extends DMDWebPage> internalErrorPageType;
public DMDLoggingRequestCycleListener() {
this(DMDInternalErrorPage.class);
}
public DMDLoggingRequestCycleListener(Class<? extends DMDWebPage> internalErrorPageType) {
this.internalErrorPageType = internalErrorPageType;
}
/**
* @see org.apache.wicket.request.cycle.AbstractRequestCycleListener#onException(org.apache.wicket.request.cycle.RequestCycle,
* java.lang.Exception)
*/
@Override
public IRequestHandler onException(RequestCycle cycle, Exception ex) {
if (!(isIgnoredException(ex))) {
if (IExceptionSettings.SHOW_INTERNAL_ERROR_PAGE.equals(NocketWebApplication.get().getExceptionSettings()
.getUnexpectedExceptionDisplay())) {
return createPageRequestHandler(new PageProvider(createInternalErrorPage(ex)));
}
}
return null;
}
/**
* Those Exceptions are ignored in our Errorhandling. Due to the fact that
* Applications using DMDWeb may invalidate their Session using their
* ErrorPage.<br>
* <br>
* If you want to change the behavior for your Application, you can
* overwrite this method.
*
* @param ex
* The thrown Exception
* @return true if the Exception is ignored, else false.
*/
protected boolean isIgnoredException(Exception ex) {
if (ex instanceof PageExpiredException) {
return true;
} else if (ex instanceof ResponseIOException) {
return true;
} else if (ex instanceof StalePageException) {
return true;
}
return false;
}
@Override
public void onExceptionRequestHandlerResolved(RequestCycle cycle,
IRequestHandler handler, Exception exception) {
super.onExceptionRequestHandlerResolved(cycle, handler, exception);
}
private RenderPageRequestHandler createPageRequestHandler(PageProvider pageProvider) {
RequestCycle requestCycle = RequestCycle.get();
if (requestCycle == null) {
throw new IllegalStateException("there is no current request cycle attached to this thread");
}
/*
* Use NEVER_REDIRECT policy to preserve the original page's URL for
* non-Ajax requests and always redirect for ajax requests
*/
RenderPageRequestHandler.RedirectPolicy redirect = RenderPageRequestHandler.RedirectPolicy.NEVER_REDIRECT;
if (isProcessingAjaxRequest()) {
redirect = RenderPageRequestHandler.RedirectPolicy.AUTO_REDIRECT;
}
return new RenderPageRequestHandler(pageProvider, redirect);
}
private boolean isProcessingAjaxRequest() {
RequestCycle rc = RequestCycle.get();
Request request = rc.getRequest();
if (request instanceof WebRequest) {
return ((WebRequest) request).isAjax();
}
return false;
}
protected DMDWebPage createInternalErrorPage(Exception ex) {
try {
Constructor<? extends DMDWebPage> ctor = internalErrorPageType.getConstructor(Throwable.class);
if (ctor == null)
ctor = internalErrorPageType.getConstructor(Exception.class);
if (ctor != null)
return ctor.newInstance(ex);
else
throw new IllegalArgumentException("No suitable constructor in page class "
+ internalErrorPageType.getName());
} catch (Exception x) {
ex.printStackTrace();
throw new SevereGUIException(x);
}
}
}