
com.sun.webui.jsf.renderkit.html.MessageGroupRenderer Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2007-2018 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://oss.oracle.com/licenses/CDDL+GPL-1.1
* or LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.webui.jsf.renderkit.html;
import com.sun.faces.annotation.Renderer;
import com.sun.webui.jsf.util.MessageUtil;
import java.beans.Beans;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.sun.webui.jsf.component.MessageGroup;
import com.sun.webui.theme.Theme;
import com.sun.webui.jsf.theme.ThemeStyles;
import com.sun.webui.jsf.util.FacesMessageUtils;
import com.sun.webui.jsf.util.RenderingUtilities;
import com.sun.webui.jsf.util.ThemeUtilities;
/**
* This class is responsible for rendering the Message component.
*/
@Renderer(@Renderer.Renders(componentFamily = "com.sun.webui.jsf.MessageGroup"))
public class MessageGroupRenderer extends AbstractRenderer {
/**
* Renders the Message component.
*
* @param context FacesContext
for the current request
* @param component UIComponent
to be rendered
* @param writer ResponseWriter
to which the element
* end should be rendered
* @exception IOException if an input/output error occurs
*/
@Override
protected void renderEnd(FacesContext context, UIComponent component,
ResponseWriter writer) throws IOException {
// End the appropriate element
MessageGroup msgGrp = (MessageGroup) component;
Iterator msgIt = null;
String forComponentId = null;
if (Beans.isDesignTime() && (msgGrp.isShowDetail() || msgGrp.isShowSummary())) {
StringBuffer resourceNameBuffer = new StringBuffer();
resourceNameBuffer.append("MessageGroup."); //NOI18N
if (msgGrp.isShowGlobalOnly()) {
resourceNameBuffer.append("global."); //NOI18N
} else {
resourceNameBuffer.append("default."); //NOI18N
}
if (msgGrp.isShowDetail() && msgGrp.isShowSummary()) {
resourceNameBuffer.append("both"); //NOI18N
} else if (msgGrp.isShowDetail()) {
resourceNameBuffer.append("detail"); //NOI18N
} else if (msgGrp.isShowSummary()) {
resourceNameBuffer.append("summary"); //NOI18N
}
String summary = MessageUtil.getMessage(context,
"com.sun.webui.jsf.renderkit.html.Bundle", //NOI18N
resourceNameBuffer.toString());
FacesMessage defaultMessage = new FacesMessage();
defaultMessage.setSummary(summary);
msgIt = Collections.singletonList(defaultMessage).iterator();
} else {
if (msgGrp.isShowGlobalOnly()) {
forComponentId = ""; // for only global messages
}
msgIt = FacesMessageUtils.getMessageIterator(context,
forComponentId, msgGrp);
}
if (msgIt.hasNext()) {
renderMessageGroup(context, msgGrp, writer, msgIt);
}
}
/**
* Renders the Message text
*
* @param context The current FacesContext
* @param component The VersionPage object to use
* @param writer The current ResponseWriter
* @param msgIt The message
*
* @exception IOException if an input/output error occurs
*/
public void renderMessageGroup(FacesContext context,
UIComponent component, ResponseWriter writer,
Iterator msgIt) throws IOException {
MessageGroup msgGrp = (MessageGroup) component;
// Get the theme
Theme theme = ThemeUtilities.getTheme(context);
// Render the style/styleClass attributes in a surrounding div
renderMessageGroupIdElement(context, msgGrp, writer);
// Render the opening table
renderOpeningTable(msgGrp, writer, theme);
FacesMessage fMsg = null;
boolean showSummary = msgGrp.isShowSummary();
boolean showDetail = msgGrp.isShowDetail();
String summaryStyle = theme.getStyleClass(
ThemeStyles.MESSAGE_GROUP_SUMMARY_TEXT);
String detailStyle = theme.getStyleClass(
ThemeStyles.MESSAGE_GROUP_TEXT);
String summary = null;
String detail = null;
// Optimization to reduce compiler construction of StringBuffer
// for constant text within the loop.
//
StringBuffer detailBuf = new StringBuffer(64).append(" ");
while (msgIt.hasNext()) {
fMsg = (FacesMessage) msgIt.next();
// Check if we should show detail or summary
if (showSummary) {
summary = fMsg.getSummary();
if ((summary != null) && (summary.length() <= 0)) {
summary = null;
}
}
if (showDetail) {
detail = fMsg.getDetail();
if ((detail != null) && (detail.length() <= 0)) {
detail = null;
}
}
if (summary == null && detail == null) {
continue;
}
// Null these variables when a severity style is found.
// Severity styles override the default styles.
//
String summaryStyleTmp = summaryStyle;
String detailStyleTmp = detailStyle;
// Why is there a div with a list with only a single
// bullet for each message ? Why not a bullet for each
// messages and one list and one div ?
//
writer.startElement("div", msgGrp); //NOI18N
writer.writeAttribute("class", //NOI18N
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_DIV),
null); //NOI18N
writer.startElement("ul", msgGrp); //NOI18N
writer.startElement("li", msgGrp); //NOI18N
// render theme based style based on severity.
String severityStyleClass = getSeverityStyleClass(fMsg, theme);
// This renders the selector on the "li" element.
// The default styles appear on the text's "span" element.
// Severity styles override default styles
//
if (severityStyleClass != null) {
writer.writeAttribute("class", severityStyleClass, //NOI18N
"styleClass"); //NOI18N
summaryStyleTmp = null;
detailStyleTmp = null;
}
if (summary != null) {
renderMessageText(msgGrp, writer, summary, summaryStyleTmp);
}
if (detail != null) {
// renderMessageText(msgGrp, writer, detail, detailStyle);
// if severity based style is set, don't use theme based
// default styles.
//
// Places a space between the summary message and
// the detail message. This should be part of the theme.
// A style for the detail message when preceded by the
// summary message.
//
if (summary != null) {
detail = detailBuf.append(detail).toString();
}
renderMessageText(msgGrp, writer, detail, detailStyleTmp);
// Rewind the buffer so only the " " exists.
//
detailBuf.setLength(1);
}
writer.endElement("li"); //NOI18N
writer.endElement("ul"); //NOI18N
writer.endElement("div"); //NOI18N
}
// Close tags
renderClosingTable(writer);
// Close the surrounding div
writer.endElement("div"); // NOI18N
}
/**
* Helper method to render opening tags for the layout table.
*
* @param msgGrp The MessageGroup object to use
* @param writer The current ResponseWriter
* @param theme The theme to use
*
* @exception IOException if an input/output error occurs
*/
public void renderOpeningTable(MessageGroup msgGrp, ResponseWriter writer,
Theme theme) throws IOException {
// Render the layout table
writer.startElement("table", msgGrp); //NOI18N
writer.writeAttribute("class", //NOI18N
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_TABLE), null);
writer.writeAttribute("border", "0", null); //NOI18N
writer.writeAttribute("cellpadding", "0", null); //NTOI18N
writer.writeAttribute("cellspacing", "0", null); //NOI18N
if (msgGrp.getToolTip() != null) {
writer.writeAttribute("title", msgGrp.getToolTip(), null); //NOI18N
} else {
// Required for A11Y
//
writer.writeAttribute("title", "", null); //NOI18N
}
writer.writeText("\n", null); //NOI18N
// Add the heading
writer.startElement("tr", msgGrp); //NOI18N
writer.startElement("th", msgGrp); //NOI18N
writer.writeAttribute("class",
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_TABLE_TITLE), null);
String title = msgGrp.getTitle();
if (title != null) {
writer.writeText(title, null);
} else {
writer.writeText(theme.getMessage("messageGroup.heading"), null);
}
writer.endElement("th");
writer.endElement("tr"); //NOI18N
writer.writeText("\n", null); //NOI18N
// We know there is at least one message
writer.startElement("tr", msgGrp); //NOI18N
writer.startElement("td", msgGrp); //NOI18N
}
/**
* Helper method to render closing tags for the layout table.
*
* @param writer The current ResponseWriter
*
* @exception IOException if an input/output error occurs
*/
public void renderClosingTable(ResponseWriter writer) throws IOException {
writer.endElement("td"); //NOI18N
writer.endElement("tr"); //NOI18N
writer.endElement("table"); //NOI18N
writer.writeText("\n", null); //NOI18N
}
/**
* Helper method to write message text.
*
* @param msgGrp The MessageGroup object to use
* @param writer The current ResponseWriter
* @param msgText The message text
* @param textStyle The text style
*
* @exception IOException if an input/output error occurs
*/
public void renderMessageText(MessageGroup msgGrp, ResponseWriter writer,
String msgText, String textStyle) throws IOException {
writer.startElement("span", msgGrp); //NOI18N
if (textStyle != null && textStyle.length() > 0) {
writer.writeAttribute("class", textStyle, "class"); //NOI18N
}
writer.writeText(msgText, null);
writer.endElement("span"); // NOI18N
}
/**
* Render the enclosing element for the MesssageGroup messages that
* is associated with the component's id.
*
* @param context The current FacesContext
* @param msgGrp The MessageGroup object to use
* @param writer The current ResponseWriter
*
* @exception IOException if an input/output error occurs
*/
private void renderMessageGroupIdElement(FacesContext context,
MessageGroup msgGrp, ResponseWriter writer) throws IOException {
String userStyle = msgGrp.getStyle();
String userStyleClass = msgGrp.getStyleClass();
String id = msgGrp.getClientId(context);
writer.startElement("div", msgGrp); //NO18N
writer.writeAttribute("id", id, "id"); //NOI18N
if (userStyle != null && userStyle.length() > 0) {
writer.writeAttribute("style", userStyle, "style"); //NOI18N
}
RenderingUtilities.renderStyleClass(context, writer, msgGrp, null);
}
/**
* Return a style class based on the FacesMesssage severity.
* If there is no style for a given severity return null.
*
* @param facesMessage The FacesMessage
* @param theme The current theme
*/
protected String getSeverityStyleClass(FacesMessage facesMessage,
Theme theme) {
// Obtain a style based on message severity
//
String severityStyleClass = null;
Severity severity = facesMessage.getSeverity();
if (severity == FacesMessage.SEVERITY_INFO) {
severityStyleClass =
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_INFO);
} else if (severity == FacesMessage.SEVERITY_WARN) {
severityStyleClass =
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_WARN);
} else if (severity == FacesMessage.SEVERITY_ERROR) {
severityStyleClass =
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_ERROR);
} else if (severity == FacesMessage.SEVERITY_FATAL) {
severityStyleClass =
theme.getStyleClass(ThemeStyles.MESSAGE_GROUP_FATAL);
}
return severityStyleClass == null || severityStyleClass.length() == 0 ? null : severityStyleClass;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy