App { public String renderPage(HttpRequest request, HttpResponse response) { RequestLookup requestLookup = createRequestLookup(request, response); API api = new API(sessionManager, authorizer, requestLookup); Theme theme = getRenderingTheme(api); try { return renderPageUri(request.getUriWithoutContextPath(), null, requestLookup, api, theme); } catch (SessionNotFoundException e) { String loginPageUri = configuration.getLoginPageUri().orElseThrow(() -> e); throw new PageRedirectException(requestLookup.getContextPath() + loginPageUri, e); } catch (PageRedirectException e) { throw e; } catch (PageNotFoundException e) { String uriWithoutContextPath = request.getUriWithoutContextPath(); String correctedUriWithoutContextPath = uriWithoutContextPath.endsWith("/") ? uriWithoutContextPath.substring(0, uriWithoutContextPath.length() - 1) : (uriWithoutContextPath + "/"); if (hasPage(correctedUriWithoutContextPath)) { if (request.isGetRequest()) { String correctedUri = request.getContextPath() + correctedUriWithoutContextPath; if (request.getQueryString() != null) { correctedUri = correctedUri + '?' + request.getQueryString(); } throw new PageRedirectException(correctedUri, e); } else { String message = e.getMessage() + " Retry with correct URI ending " + correctedUriWithoutContextPath; return renderErrorPage(new PageNotFoundException(message, e), request, response, theme); } } else { return renderErrorPage(e, request, response, theme); } } catch (HttpErrorException e) { return renderErrorPage(e, request, response, theme); } catch (PluginExecutionException e) { LOGGER.error("An error occurred while executing a plugin.", e); return renderErrorPage(new HttpErrorException(STATUS_INTERNAL_SERVER_ERROR, e.getMessage(), e), request, response, theme); } catch (RenderingException e) { LOGGER.error("An error occurred while rendering page for request '{}'.", request, e); String message = (e.getCause() != null) ? ExceptionUtils.getRootCause(e).getMessage() : e.getMessage(); return renderErrorPage(new HttpErrorException(STATUS_INTERNAL_SERVER_ERROR, message, e), request, response, theme); } } App(String name, String contextPath, Set<Component> components, Set<Theme> themes,
               Configuration configuration, Bindings bindings, I18nResources i18nResources,
               SessionManager sessionManager, Authorizer authorizer); String getName(); String getContextPath(); Map<String, Component> getComponents(); Map<String, Fragment> getFragments(); Map<String, Layout> getLayouts(); Map<String, Theme> getThemes(); Configuration getConfiguration(); String renderPage(HttpRequest request, HttpResponse response); JsonObject renderFragment(HttpRequest request, HttpResponse response); @Override int hashCode(); @Override boolean equals(Object obj); @Override String toString();  }
@Test public void testRenderPage() throws Exception { final String page1Content = "Page 1 content."; Page p1 = createPage("/a/b", page1Content); final String page2Content = "Page 2 content."; Page p2 = createPage("/x/y", page2Content); Component cmp = new Component("cmp", null, "/cmp", ImmutableSortedSet.of(p1, p2), emptySet(), emptySet(), emptySet(), null); Component rootComponent = new Component("root", null, Component.ROOT_COMPONENT_CONTEXT_PATH, emptySortedSet(), emptySet(), emptySet(), singleton(cmp), null); Configuration configuration = createConfiguration(); SessionManager sessionManager = createSessionManager(); App app = new App(null, "/test", ImmutableSet.of(cmp, rootComponent), emptySet(), configuration, null, null, sessionManager, null); String html = app.renderPage(createRequest(app.getContextPath(), "/cmp/a/b"), null); Assert.assertEquals(html, page1Content); html = app.renderPage(createRequest(app.getContextPath(), "/cmp/x/y"), null); Assert.assertEquals(html, page2Content); }