if (Static.isPreview(request) || user != null) {
response.setHeader("Cache-Control", "private, no-cache");
response.setHeader("Brightspot-Cache", "none");
}
final State mainState = State.getInstance(mainObject);
// Fake the request path in preview mode in case the servlets
// depend on it.
if (Static.isPreview(request)) {
final String previewPath = request.getParameter("_previewPath");
if (!ObjectUtils.isBlank(previewPath)) {
int colonAt = previewPath.indexOf(':');
if (colonAt > -1) {
Site previewSite = Query.
from(Site.class).
where("_id = ?", ObjectUtils.to(UUID.class, previewPath.substring(0, colonAt))).
first();
if (previewSite != null) {
Static.setSite(request, previewSite);
}
}
request = new HttpServletRequestWrapper(request) {
@Override
public String getRequestURI() {
return getContextPath() + getServletPath();
}
@Override
public StringBuffer getRequestURL() {
return new StringBuffer(getRequestURI());
}
@Override
public String getServletPath() {
return previewPath;
}
};
}
}
if (!Static.isPreview(request) &&
!mainState.isVisible()) {
SCHEDULED: {
if (user != null) {
Schedule currentSchedule = user.getCurrentSchedule();
if (currentSchedule != null &&
Query.from(Draft.class).where("schedule = ? and objectId = ?", currentSchedule, mainState.getId()).first() != null) {
break SCHEDULED;
}
} else {
if (Settings.isProduction()) {
chain.doFilter(request, response);
return;
} else {
throw new IllegalStateException(String.format(
"[%s] isn't visible!", mainState.getId()));
}
}
}
}
// If showing an invisible item, make sure all nested invisible
// items show up too.
if (!mainState.isVisible() || Static.isPreview(request)) {
mainState.setResolveInvisible(true);
}
ObjectType mainType = mainState.getType();
Page page = Static.getPage(request);
if (page == null &&
mainType != null &&
!ObjectUtils.isBlank(mainType.as(Renderer.TypeModification.class).getPath())) {
page = Application.Static.getInstance(CmsTool.class).getModulePreviewTemplate();
}
// SEO and <head>.
Map<String, Object> seo = new HashMap<String, Object>();
Seo.ObjectModification seoData = mainState.as(Seo.ObjectModification.class);
String seoTitle = seoData.findTitle();
String seoDescription = seoData.findDescription();
String seoRobots = seoData.findRobotsString();
Set<String> seoKeywords = seoData.findKeywords();
String seoKeywordsString = null;
request.setAttribute("seo", seo);
seo.put("title", seoTitle);
seo.put("description", seoDescription);
seo.put("robots", seoRobots);
if (seoKeywords != null) {
seoKeywordsString = seoKeywords.toString();
seo.put("keywords", seoKeywords);
seo.put("keywordsString", seoKeywordsString);
}
PageStage stage = new PageStage(getServletContext(), request);
request.setAttribute("stage", stage);
stage.setMetaProperty("og:type", mainType.as(Seo.TypeModification.class).getOpenGraphType());
if (mainType != null &&
!ObjectUtils.isBlank(mainType.as(Renderer.TypeModification.class).getEmbedPath())) {
stage.findOrCreateHeadElement("link",
"rel", "alternate",
"type", "application/json+oembed").
getAttributes().
put("href", JspUtils.getAbsoluteUrl(request, "",
"_embed", true,
"_format", "oembed"));
}
stage.setTitle(seoTitle);
stage.setDescription(seoDescription);
stage.setMetaName("robots", seoRobots);
stage.setMetaName("keywords", seoKeywordsString);
stage.update(mainObject);
// Try to set the right content type based on the extension.
String contentType = URLConnection.getFileNameMap().getContentTypeFor(servletPath);
response.setContentType((ObjectUtils.isBlank(contentType) ? "text/html" : contentType) + ";charset=UTF-8");
// Disable Webkit's XSS Auditor since it often interferes with
// how preview works.
if (Static.isPreview(request)) {
response.setHeader("X-XSS-Protection", "0");
}
// Render the page.
if (Static.isInlineEditingAllContents(request)) {
response = new LazyWriterResponse(request, response);
}
writer = new HtmlWriter(response.getWriter());
((HtmlWriter) writer).putAllStandardDefaults();
request.setAttribute("sections", new PullThroughCache<String, Section>() {
@Override
protected Section produce(String name) {
return Query.from(Section.class).where("internalName = ?", name).first();
}
});
beginPage(request, response, writer, page);
if (!response.isCommitted()) {
request.getSession();
}
String context = request.getParameter("_context");
boolean contextNotBlank = !ObjectUtils.isBlank(context);
boolean embed = ObjectUtils.coalesce(
ObjectUtils.to(Boolean.class, request.getParameter("_embed")),
contextNotBlank);
String layoutPath = findLayoutPath(mainObject, embed);
if (page != null && ObjectUtils.isBlank(layoutPath)) {
layoutPath = findLayoutPath(page, embed);
if (!embed && ObjectUtils.isBlank(layoutPath)) {
layoutPath = page.getRendererPath();
}
}
if (ObjectUtils.isBlank(layoutPath) &&
Static.isPreview(request)) {
layoutPath = findLayoutPath(mainObject, true);
}
String typePath = mainType.as(Renderer.TypeModification.class).getPath();
boolean rendered = false;
try {
if (contextNotBlank) {
ContextTag.Static.pushContext(request, context);
}
if (!ObjectUtils.isBlank(layoutPath)) {
rendered = true;
JspUtils.include(request, response, writer, StringUtils.ensureStart(layoutPath, "/"));
} else if (page != null) {
Page.Layout layout = page.getLayout();
if (layout != null) {
rendered = true;
renderSection(request, response, writer, layout.getOutermostSection());
}
}
if (!rendered && !embed && !ObjectUtils.isBlank(typePath)) {
rendered = true;
JspUtils.include(request, response, writer, StringUtils.ensureStart(typePath, "/"));
}
if (!rendered && mainObject instanceof Renderer) {
rendered = true;
((Renderer) mainObject).renderObject(request, response, (HtmlWriter) writer);
}
} finally {
if (contextNotBlank) {
ContextTag.Static.popContext(request);
}
}
if (!rendered) {
if (Settings.isProduction()) {
chain.doFilter(request, response);
return;
} else {
StringBuilder message = new StringBuilder();
if (embed) {
message.append("@Renderer.EmbedPath required on [");
message.append(mainObject.getClass().getName());
message.append("] to render it in [");
message.append(ObjectUtils.isBlank(context) ? "_embed" : context);
message.append("] context");
} else {
message.append("@Renderer.Path or @Renderer.LayoutPath required on [");
message.append(mainObject.getClass().getName());
message.append("] to render it");
}
message.append(" (Object: [");
message.append(mainState.getLabel());
message.append("], ID: [");
message.append(mainState.getId().toString().replaceAll("-", ""));
message.append("])!");
throw new IllegalStateException(message.toString());
}
}
endPage(request, response, writer, page);
if (Static.isInlineEditingAllContents(request)) {
LazyWriterResponse lazyResponse = (LazyWriterResponse) response;
Map<String, String> map = new HashMap<String, String>();
State state = State.getInstance(mainObject);
StringBuilder marker = new StringBuilder();
map.put("id", state.getId().toString());
map.put("label", state.getLabel());
map.put("typeLabel", state.getType().getLabel());
marker.append("<span class=\"cms-mainObject\" style=\"display: none;\" data-object=\"");
marker.append(StringUtils.escapeHtml(ObjectUtils.toJson(map)));
marker.append("\"></span>");
lazyResponse.getLazyWriter().writeLazily(marker.toString());
}
} finally {
Database.Static.restoreDefault();
if (response instanceof LazyWriterResponse) {
((LazyWriterResponse) response).getLazyWriter().writePending();
}
}
if (Settings.isDebug() ||
(Static.isPreview(request) &&
!Boolean.TRUE.equals(request.getAttribute(PERSISTENT_PREVIEW_ATTRIBUTE)))) {
return;
}
String contentType = response.getContentType();
if (contentType == null ||
!StringUtils.ensureEnd(contentType, ";").startsWith("text/html;")) {
return;
}
Object mainObject = PageFilter.Static.getMainObject(request);
if (mainObject != null && user != null) {
if (!JspUtils.isError(request)) {
user.saveAction(request, mainObject);
}
@SuppressWarnings("all")
ToolPageContext page = new ToolPageContext(getServletContext(), request, response);
State mainState = State.getInstance(mainObject);
page.setDelegate(writer instanceof HtmlWriter ? (HtmlWriter) writer : new HtmlWriter(writer));
page.writeStart("style", "type", "text/css");
page.writeCss(".bsp-inlineEditorMain",
"background", "rgba(32, 52, 63, 0.8) !important",
"color", "white !important",
"font-family", "'Helvetica Neue', sans-serif !important",
"font-size", "13px !important",
"font-weight", "normal !important",
"left", "0 !important",
"line-height", "21px !important",
"list-style", "none !important",
"margin", "0 !important",
"padding", "0 !important",
"position", "fixed !important",
"top", "0 !important",
"z-index", "1000001 !important");
page.writeCss(".bsp-inlineEditorMain a",
"color", "#54d1f0 !important",
"display", "block !important",
"float", "left !important",
"max-width", "250px",
"overflow", "hidden",
"padding", "5px !important",
"text-overflow", "ellipsis",
"white-space", "nowrap");
page.writeCss(".bsp-inlineEditorMain a:hover",
"background", "#54d1f0 !important",
"color", "black !important");
page.writeCss(".bsp-inlineEditorMain .bsp-inlineEditorMain_logo",
"padding", "8px 10px !important");
page.writeCss(".bsp-inlineEditorMain .bsp-inlineEditorMain_logo:hover",
"background", "transparent !important");
page.writeCss(".bsp-inlineEditorMain .bsp-inlineEditorMain_logo img",
"display", "block !important");
page.writeCss(".bsp-inlineEditorMain .bsp-inlineEditorMain_remove",
"color", "#ff0e40 !important",
"font-size", "21px");
page.writeEnd();
page.writeStart("div", "class", "bsp-inlineEditorMain");
page.writeStart("a",
"class", "bsp-inlineEditorMain_logo",
"target", "_blank",
"href", page.fullyQualifiedToolUrl(CmsTool.class, "/"));
page.writeElement("img",
"src", page.cmsUrl("/style/brightspot.png"),
"alt", "Brightspot",
"width", 104,
"height", 14);
page.writeEnd();
Schedule currentSchedule = user.getCurrentSchedule();
if (currentSchedule != null) {
page.writeStart("a",
"target", "_blank",
"href", page.fullyQualifiedToolUrl(CmsTool.class, "/scheduleEdit", "id", currentSchedule.getId()));
page.writeHtml("Current Schedule: ");
page.writeObjectLabel(currentSchedule);
page.writeEnd();
}
page.writeStart("a",
"target", "_blank",
"href", page.fullyQualifiedToolUrl(CmsTool.class, "/content/edit.jsp", "id", State.getInstance(mainObject).getId()));
page.writeHtml("Edit ");
page.writeTypeObjectLabel(mainObject);
page.writeEnd();
if (Boolean.TRUE.equals(request.getAttribute(PERSISTENT_PREVIEW_ATTRIBUTE))) {
page.writeStart("a",
"target", "_blank",
"href", page.url("", "_clearPreview", true));
page.writeHtml("(Previewing - View Live Instead)");
page.writeEnd();
}
page.writeStart("a",
"class", "bsp-inlineEditorMain_remove",
"href", "#",
"onclick",
"var main = this.parentNode," +
"contents = this.ownerDocument.getElementById('bsp-inlineEditorContents');" +
"main.parentNode.removeChild(main);" +
"if (contents) {" +
"contents.parentNode.removeChild(contents);" +
"}" +
"return false;");
page.writeHtml("\u00d7");
page.writeEnd();
page.writeEnd();
if (user.getInlineEditing() != ToolUser.InlineEditing.DISABLED) {
page.writeStart("iframe",
"class", "cms-inlineEditor",
"id", "bsp-inlineEditorContents",
"onload", "this.style.visibility = 'visible';",
"scrolling", "no",
"src", page.cmsUrl("/inlineEditor", "id", mainState.getId()),
"style", page.cssString(
"border", "none",
"height", 0,
"left", 0,
"margin", 0,