001    package org.trails.exception;
002    
003    import java.io.IOException;
004    
005    import org.apache.commons.logging.Log;
006    import org.apache.commons.logging.LogFactory;
007    import org.apache.tapestry.IPage;
008    import org.apache.tapestry.IRequestCycle;
009    import org.apache.tapestry.error.ExceptionPresenterImpl;
010    import org.trails.exception.TrailsRuntimeException;
011    import org.trails.page.PageResolver;
012    import org.trails.page.PageType;
013    
014    /* kaosko 2007-06-18:
015     * I would have really liked to implement the exception presenter only as a handler in pipeline
016     * (as described at http://mail-archives.apache.org/mod_mbox/tapestry-dev/200606.mbox/%3C000a01c6906b$6ba3b8b0$6601a8c0@CARMANI9300%3E)
017     * It required some changed in Hivemind core that were already implemented in Hivemind 1.1.2 which was never
018     * released even though it apparently came very close. I've inquired about the status of 1.1.2 on Hivemind list
019     */
020    public class ApplicationExceptionPresenterImpl extends ExceptionPresenterImpl {
021            private static final Log log = LogFactory.getLog(ApplicationExceptionPresenterImpl.class);
022            private PageResolver pageResolver;
023            
024            public void presentException(IRequestCycle cycle, Throwable throwable) {
025                    if (throwable.getCause() == null || !(throwable.getCause() instanceof TrailsRuntimeException)) {
026                            super.presentException(cycle, throwable);
027                            return;
028                    }
029                    TrailsRuntimeException trailsRuntimeException = (TrailsRuntimeException)throwable.getCause();
030    
031                    if (log.isWarnEnabled())
032                    {
033                            if (trailsRuntimeException.getEntityType() == null)
034                            {
035                                    log.warn("Trails specific exception happened while handling unknown entity, caused by: " + throwable.getCause().getMessage());
036                            } else
037                            {
038                                    log.warn("Trails specific exception happened while handling entity type " + trailsRuntimeException.getEntityType().getName() + ", caused by: " + throwable.getCause().getMessage());
039                            }
040                    }
041                    log.debug("The problem was caused by: ", throwable.getCause());
042                    IPage page = pageResolver.resolvePage(cycle, trailsRuntimeException.getEntityType(), PageType.EXCEPTION);
043                    cycle.activate(page);
044                    try {
045                            cycle.getResponseBuilder().renderResponse(cycle);
046                    } catch (IOException e) {
047                            log.error("Couldn't render a Trails specific error page because of : ", e);
048                            super.presentException(cycle, throwable);
049                    }
050            }
051    
052            public void setPageResolver(PageResolver pageResolver) {
053                    this.pageResolver = pageResolver;
054            }
055    }