// Get the renderer id that has been registered with the url. For this,
// we first have to load the page data, then get the associated renderer
// bundle.
try {
Page page = null;
ResourceURI pageURI = null;
Site site = request.getSite();
// Check if a page was passed as an attribute
if (request.getAttribute(WebloungeRequest.PAGE) != null) {
page = (Page) request.getAttribute(WebloungeRequest.PAGE);
pageURI = page.getURI();
}
// Load the page from the content repository
else {
ContentRepository contentRepository = site.getContentRepository();
if (contentRepository == null) {
logger.debug("No content repository found for site '{}'", site);
return false;
} else if (contentRepository.isIndexing()) {
logger.debug("Content repository of site '{}' is currently being indexed", site);
DispatchUtils.sendServiceUnavailable(request, response);
return true;
}
ResourceURI requestURI = null;
ResourceURI requestedURI = null;
// Load the page. Note that we are taking care of the special case where
// a user may have created a page with a url that matches a valid
// language identifier, in which case it would have been stripped from
// request.getUrl().
try {
if (action != null) {
pageURI = getPageURIForAction(action, request);
requestURI = pageURI;
} else if (path.startsWith(URI_PREFIX)) {
String uriSuffix = StringUtils.substringBefore(path.substring(URI_PREFIX.length()), "/");
uriSuffix = URLDecoder.decode(uriSuffix, "utf-8");
ResourceURI uri = new PageURIImpl(site, null, uriSuffix, request.getVersion());
requestURI = uri;
WebUrl requestedUrl = request.getRequestedUrl();
if (requestedUrl.hasLanguagePathSegment()) {
String requestedPath = UrlUtils.concat(path, request.getLanguage().getIdentifier());
String requestedUriSuffix = StringUtils.substringBefore(requestedPath.substring(URI_PREFIX.length()), "/");
requestedUriSuffix = URLDecoder.decode(requestedUriSuffix, "utf-8");
requestedURI = new PageURIImpl(site, requestedUriSuffix, null, request.getVersion());
}
} else {
long version = isEditing ? Resource.WORK : Resource.LIVE;
ResourceURI uri = new PageURIImpl(request);
uri.setVersion(version);
requestURI = uri;
WebUrl requestedUrl = request.getRequestedUrl();
if (requestedUrl.hasLanguagePathSegment()) {
String requestedPath = UrlUtils.concat(path, request.getLanguage().getIdentifier());
requestedPath = URLDecoder.decode(requestedPath, "utf-8");
requestedURI = new PageURIImpl(site, requestedPath, null, version);
}
}
// Is this a request with potential path clashes?
if (requestedURI != null) {
long version = requestedURI.getVersion();
if (contentRepository.existsInAnyVersion(requestedURI)) {
if (!isEditing && version == Resource.LIVE && contentRepository.exists(requestedURI)) {
pageURI = requestedURI;
((WebloungeRequestImpl) request).setLanguage(request.getSessionLanguage());
} else if (isEditing && version == Resource.WORK && !contentRepository.exists(requestedURI)) {
requestedURI.setVersion(Resource.LIVE);
pageURI = requestedURI;
((WebloungeRequestImpl) request).setLanguage(request.getSessionLanguage());
} else if (isEditing && version == Resource.WORK && !contentRepository.exists(requestedURI)) {
pageURI = requestedURI;
((WebloungeRequestImpl) request).setLanguage(request.getSessionLanguage());
}
}
}
// Does the page exist?
if (pageURI == null && contentRepository.existsInAnyVersion(requestURI)) {
long version = requestURI.getVersion();
// If the work version is requested, we need to make sure
// a) it exists and b) the user is in editing mode
if (version == Resource.WORK && isEditing) {
if (contentRepository.exists(requestURI)) {
pageURI = requestURI;
} else {
requestURI.setVersion(Resource.LIVE);
if (contentRepository.exists(requestURI))
pageURI = requestURI;
}
} else if (contentRepository.exists(requestURI)) {
pageURI = requestURI;
}
}
// Did we find a matching uri?
if (pageURI == null) {
DispatchUtils.sendNotFound(request, response);
return true;
}
page = (Page) contentRepository.get(pageURI);
if (page == null) {
DispatchUtils.sendNotFound(request, response);
return true;
}
} catch (ContentRepositoryException e) {
logger.error("Unable to load page {} from {}: {}", new Object[] {
pageURI,
contentRepository,
e.getMessage(),
e });
DispatchUtils.sendInternalError(request, response);
return true;
}
}
// Check the request method. This handler only supports GET, POST and
// OPTIONS
String requestMethod = request.getMethod().toUpperCase();
if ("OPTIONS".equals(requestMethod)) {
String verbs = "OPTIONS, GET, POST";
logger.trace("Answering options request to {} with {}", url, verbs);
response.setHeader("Allow", verbs);
response.setContentLength(0);
return true;
} else if (!"GET".equals(requestMethod) && !"POST".equals(requestMethod) && !RequestUtils.containsAction(request)) {
logger.debug("Url {} does not handle {} requests", url, requestMethod);
DispatchUtils.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, request, response);
return true;
}
// Is it published?
if (!page.isPublished() && !(page.getVersion() == Resource.WORK)) {
logger.debug("Access to unpublished page {}", pageURI);
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return true;
}
// Can the page be accessed by the current user?
User user = request.getUser();
try {
// TODO: Check permission
// PagePermission p = new PagePermission(page, user);
// AccessController.checkPermission(p);
} catch (SecurityException e) {
logger.warn("Accessed to page {} denied for user {}", pageURI, user);
DispatchUtils.sendAccessDenied(request, response);
return true;
}
// Check for explicit no cache instructions
boolean ignoreCache = request.getParameter(ResponseCache.NOCACHE_PARAM) != null;
// Check if the page is already part of the cache. If so, our task is
// already done!
if (!ignoreCache && request.getVersion() == Resource.LIVE && !isEditing) {
// Create the set of tags that identify the page
CacheTagSet cacheTags = createPrimaryCacheTags(request);
if (action == null) {
long expirationTime = Renderer.DEFAULT_VALID_TIME;
long revalidationTime = Renderer.DEFAULT_RECHECK_TIME;
// Check if the page is already part of the cache
if (response.startResponse(cacheTags.getTags(), expirationTime, revalidationTime)) {
logger.debug("Page handler answered request for {} from cache", request.getUrl());
return true;
}
}
processingMode = Mode.Cached;
cacheTags.add(CacheTag.Resource, page.getURI().getIdentifier());
response.addTags(cacheTags);
} else if (Http11Constants.METHOD_HEAD.equals(requestMethod)) {
// handle HEAD requests
Http11Utils.startHeadResponse(response);
processingMode = Mode.Head;
} else if (request.getVersion() == Resource.WORK) {
response.setCacheExpirationTime(0);
}
// Set the default maximum render and valid times for pages
response.setClientRevalidationTime(Renderer.DEFAULT_RECHECK_TIME);
response.setCacheExpirationTime(Renderer.DEFAULT_VALID_TIME);
// Store the page in the request
request.setAttribute(WebloungeRequest.PAGE, page);
// Get hold of the page template
PageTemplate template = null;
try {
template = getPageTemplate(page, request);
template.setEnvironment(request.getEnvironment());
} catch (IllegalStateException e) {
logger.debug(e.getMessage());
DispatchUtils.sendInternalError(request, response);
return true;
}
// Does the template support the requested flavor?
if (!template.supportsFlavor(contentFlavor)) {
logger.warn("Template '{}' does not support requested flavor {}", template, contentFlavor);
DispatchUtils.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, request, response);
return true;
}
// Suggest a last modified data. Note that this may not be the final date
// as the page may contain content embedded from other pages that feature
// more recent modification dates
response.setModificationDate(page.getLastModified());
// Set the content type
String characterEncoding = response.getCharacterEncoding();
if (StringUtils.isNotBlank(characterEncoding))
response.setContentType("text/html; charset=" + characterEncoding.toLowerCase());