}
final String contentType = writer.getContentTypeWithCharSet();
ResponseUtils.ensureContentTypeHeader(facesContext, contentType);
final String clientId = page.getClientId(facesContext);
final ClientProperties client = ClientProperties.getInstance(facesContext);
final ProjectStage projectStage = tobagoConfig.getProjectStage();
final boolean developmentMode = projectStage == ProjectStage.Development;
final boolean productionMode = projectStage == ProjectStage.Production;
int clientLogSeverity = 2;
if (developmentMode) {
final String severity = (String) externalContext.getRequestMap().get(CLIENT_DEBUG_SEVERITY);
if (LOG.isDebugEnabled()) {
LOG.debug("get " + CLIENT_DEBUG_SEVERITY + " = " + severity);
}
if (severity != null) {
try {
int index = severity.indexOf(';');
if (index == -1) {
index = severity.length();
}
clientLogSeverity = Integer.parseInt(severity.substring(0, index));
} catch (final NumberFormatException e) {
// ignore; use default
}
}
}
final boolean preventFrameAttacks = tobagoConfig.isPreventFrameAttacks();
if (!FacesContextUtils.isAjax(facesContext)) {
final String title = (String) page.getAttributes().get(Attributes.LABEL);
writer.startElement(HtmlElements.HEAD, null);
// meta tags
// this is needed, because websphere 6.0? ignores the setting of the content type on the response
writer.startElement(HtmlElements.META, null);
writer.writeAttribute(HtmlAttributes.HTTP_EQUIV, "Content-Type", false);
writer.writeAttribute(HtmlAttributes.CONTENT, contentType, false);
writer.endElement(HtmlElements.META);
// title
writer.startElement(HtmlElements.TITLE, null);
writer.writeText(title != null ? title : "");
writer.endElement(HtmlElements.TITLE);
final Theme theme = client.getTheme();
// style files
for (final String styleFile : theme.getStyleResources(productionMode)) {
writeStyle(facesContext, writer, styleFile);
}
for (final String styleFile : FacesContextUtils.getStyleFiles(facesContext)) {
writeStyle(facesContext, writer, styleFile);
}
if (!productionMode) {
checkDuplicates(theme.getStyleResources(productionMode), FacesContextUtils.getStyleFiles(facesContext));
}
final String icon = page.getApplicationIcon();
if (icon != null) {
final String href;
if (ResourceManagerUtils.isAbsoluteResource(icon)) {
href = icon;
} else {
href = ResourceManagerUtils.getImageWithPath(facesContext, icon);
}
if (href != null) {
writer.startElement(HtmlElements.LINK, null);
if (href.endsWith(".ico")) {
writer.writeAttribute(HtmlAttributes.REL, "shortcut icon", false);
writer.writeAttribute(HtmlAttributes.HREF, href, false);
} else {
// XXX IE only supports ICO files for favicons
writer.writeAttribute(HtmlAttributes.REL, "icon", false);
writer.writeAttribute(HtmlAttributes.TYPE, MimeTypeUtils.getMimeTypeForFile(href), false);
writer.writeAttribute(HtmlAttributes.HREF, href, false);
}
writer.endElement(HtmlElements.LINK);
} else {
LOG.warn("Application icon '" + icon + "' not found!");
}
}
// style sniplets
final Set<String> styleBlocks = FacesContextUtils.getStyleBlocks(facesContext);
if (styleBlocks.size() > 0) {
writer.startElement(HtmlElements.STYLE, null);
writer.flush(); // is needed in some cases, e. g. TOBAGO-1094
for (final String cssBlock : styleBlocks) {
writer.write(cssBlock);
}
writer.endElement(HtmlElements.STYLE);
}
// render remaining script tags
for (final String scriptFile : theme.getScriptResources(productionMode)) {
encodeScript(facesContext, writer, scriptFile);
}
for (final String scriptFile : FacesContextUtils.getScriptFiles(facesContext)) {
encodeScript(facesContext, writer, scriptFile);
}
if (!productionMode) {
checkDuplicates(theme.getScriptResources(productionMode), FacesContextUtils.getScriptFiles(facesContext));
}
writer.startJavascript();
// onload script
writeEventFunction(writer, FacesContextUtils.getOnloadScripts(facesContext), "load", false);
// onunload script
writeEventFunction(writer, FacesContextUtils.getOnunloadScripts(facesContext), "unload", false);
// onexit script
writeEventFunction(writer, FacesContextUtils.getOnexitScripts(facesContext), "exit", false);
writeEventFunction(writer, FacesContextUtils.getOnsubmitScripts(facesContext), "submit", true);
int debugCounter = 0;
for (final String scriptBlock : FacesContextUtils.getScriptBlocks(facesContext)) {
if (LOG.isDebugEnabled()) {
LOG.debug("write scriptblock " + ++debugCounter + " :\n" + scriptBlock);
}
writer.write(scriptBlock);
writer.write('\n');
}
writer.endJavascript();
writer.endElement(HtmlElements.HEAD);
}
if (portlet) {
writer.startElement(HtmlElements.DIV, page);
writer.writeClassAttribute(Classes.create(page, Markup.PORTLET));
} else {
writer.startElement(HtmlElements.BODY, page);
writer.writeClassAttribute(Classes.create(page));
}
writer.writeIdAttribute(clientId);
HtmlRendererUtils.writeDataAttributes(facesContext, writer, page);
HtmlRendererUtils.renderCommandFacet(page, facesContext, writer);
writer.startElement(HtmlElements.FORM, page);
if (preventFrameAttacks && !FacesContextUtils.isAjax(facesContext)) {
writer.writeClassAttribute(Classes.create(page, "preventFrameAttacks", Markup.NULL));
}
writer.writeAttribute(HtmlAttributes.ACTION, formAction, true);
if (partialAction != null) {
writer.writeAttribute(DataAttributes.PARTIAL_ACTION, partialAction, true);
}
if (LOG.isDebugEnabled()) {
LOG.debug("partial action = " + partialAction);
}
writer.writeIdAttribute(page.getFormId(facesContext));
writer.writeAttribute(HtmlAttributes.METHOD, getMethod(page), false);
final String enctype = FacesContextUtils.getEnctype(facesContext);
if (enctype != null) {
writer.writeAttribute(HtmlAttributes.ENCTYPE, enctype, false);
}
// TODO: enable configuration of 'accept-charset'
writer.writeAttribute(HtmlAttributes.ACCEPT_CHARSET, AbstractUIPage.FORM_ACCEPT_CHARSET, false);
// TODO evaluate 'accept' attribute usage
//writer.writeAttribute(HtmlAttributes.ACCEPT, );
writer.startElement(HtmlElements.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "form-action");
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "form-action");
writer.endElement(HtmlElements.INPUT);
writer.startElement(HtmlElements.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "context-path");
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "context-path");
writer.writeAttribute(HtmlAttributes.VALUE, externalContext.getRequestContextPath(), true);
writer.endElement(HtmlElements.INPUT);
writer.startElement(HtmlElements.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "action-position");
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "action-position");
writer.endElement(HtmlElements.INPUT);
writer.startElement(HtmlElements.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "form-clientDimension");
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "form-clientDimension");
writer.endElement(HtmlElements.INPUT);
final boolean calculateScrollbarWeight =
client.getVerticalScrollbarWeight() == null || client.getHorizontalScrollbarWeight() == null;
if (calculateScrollbarWeight) {
writer.startElement(HtmlElements.DIV, null);
writer.writeClassAttribute(Classes.create(page, "scrollbarWeight", Markup.NULL));
writer.startElement(HtmlElements.DIV, null);
writer.endElement(HtmlElements.DIV);
writer.endElement(HtmlElements.DIV);
}
writer.startElement(HtmlElements.INPUT, null);
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.HIDDEN, false);
writer.writeNameAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "scrollbarWeight");
writer.writeIdAttribute(clientId + ComponentUtils.SUB_SEPARATOR + "scrollbarWeight");
if (client.getVerticalScrollbarWeight() != null && client.getHorizontalScrollbarWeight() != null) {
writer.writeAttribute(
HtmlAttributes.VALUE,
client.getVerticalScrollbarWeight().getPixel() + ";" + client.getHorizontalScrollbarWeight().getPixel(),
false);
}
writer.endElement(HtmlElements.INPUT);
if (TobagoConfig.getInstance(FacesContext.getCurrentInstance()).isCheckSessionSecret()) {