String completeUrl = path.getCompleteURL();
HttpSession session = request.getSession();
// Fetch the database
WGDatabase database = path.getDatabase();
if (database == null) {
throw new HttpErrorException(404, "No database of key " + path.getDatabaseKey(), null);
}
// Determine requested mime type and type key
String mediaKey = path.getMediaKey();
if (mediaKey == null) {
mediaKey = database.getAttribute(WGACore.DBATTRIB_DEFAULT_MEDIAKEY).toString();
}
MediaKey mediaKeyObj = _core.getMediaKey(mediaKey);
String mimeType = mediaKeyObj.getMimeType();
response.setContentType(mimeType);
// Look if a session cookie has to be set
_core.setSessionCookie(request, response, database);
// Determine the content for this request
WGContent content = path.getContent();
// Context request, if content key filled or we have a title path
if (content != null) {
if (!content.mayBePublished(isBrowserInterface(session) || isAuthoringMode(database.getDbReference(), session), WGContent.DISPLAYTYPE_NONE)) {
sendNoContentNotification(path, request, response, database);
return;
}
if (content.isVirtual()) {
if (isBrowserInterface(session)) {
if (!content.getStatus().equals(WGContent.STATUS_DRAFT) && request.getParameter("forceVLink") == null) {
String url = getVirtualContentURL(request, database, path, content);
sendRedirect(response, url);
return;
}
}
else {
sendRedirect(response, buildVirtualLink(content, request, path.getMediaKey(), path.getLayoutKey()));
return;
}
}
}
// Contextless request. We use a dummy content
else {
content = database.getDummyContent(path.getRequestLanguage());
}
// Test browsability of content
if (!content.isDummy() && getBrowsingSecurity(database) <= BrowsingSecurity.NO_BROWSING) {
throw new HttpErrorException(java.net.HttpURLConnection.HTTP_FORBIDDEN, "Browsing not allowed in database '" + path.getDatabaseKey() + "'", path.getDatabaseKey());
}
// Drop cache if requested by url param
if (request.getQueryString() != null && request.getQueryString().toLowerCase().indexOf("dropcache") != -1 && isAdminLoggedIn(request)) {
content.dropCache();
}
// Personalize
TMLUserProfile tmlUserProfile = null;
try {
if (_core.isPersonalisationEnabled()) {
tmlUserProfile = this.fetchUserProfile(request, response, database, session);
if (tmlUserProfile != null && !tmlUserProfile.getprofile().isDeleted()) {
if (!isBrowserInterface(session)) {
this.registerHit(tmlUserProfile.getprofile(), database, content);
}
}
}
}
catch (WGAPIException e) {
_log.error("Unable to personalize tmlrequest.", e);
}
// Set context attributes for tml
request.setAttribute(WGACore.ATTRIB_MAINCONTEXT, content);
request.setAttribute(WGACore.ATTRIB_WGPPATH, path.getPublisherURL());
request.setAttribute(WGACore.ATTRIB_TAGIDS, WGUtils.createSynchronizedMap());
request.setAttribute(WGACore.ATTRIB_TMLCONTEXTS, WGUtils.createSynchronizedMap());
request.setAttribute(WGACore.ATTRIB_REQUESTURL, completeUrl);
request.setAttribute(WGACore.ATTRIB_MIMETYPE, mimeType);
request.setAttribute(WGACore.ATTRIB_MEDIAKEY, mediaKey);
request.setAttribute(WGACore.ATTRIB_REQUESTTYPE, REQUESTTYPE_TML);
if (mediaKeyObj.isBinary()) {
request.setAttribute(WGACore.ATTRIB_SERVLETRESPONSE, response);
}
// Determine tml design for this request
WGTMLModule tmlLib = null;
if (path.getLayoutKey() != null) {
tmlLib = (WGTMLModule) database.getDesignObject(WGDocument.TYPE_TML, path.getLayoutKey(), mediaKey);
if (tmlLib != null && tmlLib.isDirectAccessAllowed() == false) {
throw new HttpErrorException(java.net.HttpURLConnection.HTTP_FORBIDDEN, "This design is not allowed for direct access: " + tmlLib.getName() + " (" + tmlLib.getMediaKey() + ")", path
.getDatabaseKey());
}
}
else {
WGStructEntry entry = content.getStructEntry();
if (entry == null) {
throw new HttpErrorException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Content " + content.getContentKey().toString() + " has no struct entry", path.getDatabaseKey());
}
tmlLib = entry.getOuterLayout(mediaKey);
}
if (tmlLib == null || tmlLib.isDummy()) {
if (path.getLayoutKey() != null) {
throw new HttpErrorException(404, "No WebTML layout '" + path.getLayoutKey() + "' for media key '" + mediaKey + "' available in app '" + database.getDbReference() + "'", path.getDatabaseKey());
}
else {
throw new HttpErrorException(500, "Outer layout of struct entry '" + content.getStructEntry().getTitle() + "(" + content.getStructEntry().getStructKey() + ")"
+ "' not available for media key '" + mediaKey + "'", path.getDatabaseKey());
}
}
request.setAttribute(WGACore.ATTRIB_OUTER_DESIGN, tmlLib.getName());
// TML Cache control
if (tmlLib.isCacheable()) {
response.setHeader("Cache-Control", "must-revalidate");
long lastModified;
// determine lastModified
// - last modified of binary response depends only on resource
// change date
// - last change date of textual response additionally depends on
// character encoding change date
if (isBinary(response)) {
lastModified = getCore().getDeployer().getLastChangedOrDeployed(database).getTime();
}
else {
lastModified = Math.max(getCore().getDeployer().getLastChangedOrDeployed(database).getTime(), _core.getCharacterEncodingLastModified());
lastModified = Math.max(lastModified, _core.getDesignEncodingLastModified(database.getDbReference()));
}
// Test modified since
if (browserCacheIsValid(request, lastModified)) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);