All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.webui.jsf.renderkit.html.CommonTaskRenderer Maven / Gradle / Ivy

/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at
 * https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL
 * Header Notice in each file and include the License file
 * at https://woodstock.dev.java.net/public/CDDLv1.0.html.
 * If applicable, add the following below the CDDL Header,
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
 */
package com.sun.webui.jsf.renderkit.html;

import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Iterator;
import java.beans.Beans;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.component.UIParameter;
import javax.faces.event.ActionEvent;
import com.sun.faces.annotation.Renderer;
import com.sun.webui.jsf.component.util.Util;
import com.sun.webui.jsf.util.ConversionUtilities;
import com.sun.webui.jsf.util.ThemeUtilities;
import com.sun.webui.jsf.util.JavaScriptUtilities;
import com.sun.webui.jsf.util.RenderingUtilities;
import com.sun.webui.theme.Theme;
import com.sun.webui.jsf.theme.ThemeImages;
import com.sun.webui.jsf.theme.ThemeStyles;
import com.sun.webui.html.HTMLAttributes;
import com.sun.webui.html.HTMLElements;
import com.sun.webui.jsf.component.CommonTask;
import com.sun.webui.jsf.component.CommonTasksGroup;
import com.sun.webui.jsf.component.CommonTasksSection;
import com.sun.webui.jsf.component.ImageHyperlink;
import com.sun.webui.jsf.component.ImageComponent;
import com.sun.webui.jsf.component.Icon;

/**
 * 

Renderer for a {@link com.sun.webui.jsf.component.CommonTask} component.

*/ @Renderer(@Renderer.Renders(componentFamily = "com.sun.webui.jsf.CommonTask")) public class CommonTaskRenderer extends AbstractRenderer { /** *

The set of integer pass-through attributes to be rendered.

*/ private static final String integerAttributes[] = {"tabIndex"}; //NOI18N /** *

Tooltip to be rendered for the "i" image. */ private static final String INFO_IMAGE_TOOLTIP = "commonTasks.infoImageTooltip"; //NOI18N /** *

Tooltip to be rendered for the close image. */ private static final String CLOSE_IMAGE_TOOLTIP = "commonTasks.closeImageTooltip"; //NOI18N /* *

Tooltip to be rendered for the common task overview image. */ private static final String OVERVIEW_IMAGE_TOOLTIP = "commonTasks.overviewImageTooltip"; //NOI18N /** *

The set of String pass-through attributes to be rendered.

*/ private static final String stringAttributes[] = {"onBlur", "onFocus", "onDblClick", "onKeyDown", "onKeyPress", "onMouseUp", //NOI18N "onKeyUp", "onMouseDown", "onMouseMove", "onMouseOut", "onMouseOver"}; //NOI18N /** *Append this string for the id for "i" image */ private static final String TOGGLE_IMAGE = "_toggleImg"; /** *Append this string for the id for info panel close link. */ private static final String CLOSE_IMAGE = "_closeImg"; /** *Append this string for the id for spacer image. */ private static final String SPACER_IMAGE = "_spacerImg"; /** *Append this string for the id of the toggle panel. */ private static final String INFO_DIV = "_info"; /** *Append this string for the id of title in info panel. */ private static final String INFO_TITLE = "_infoTitle"; /** *Append this string for the id of text in info panel. */ private static final String INFO_TEXT = "_infoText"; /** *Append this string for the id of the default hyperlink of commonTask */ private static final String COMMONTASK_LINK = "_link"; /** *Append this string for the id of div for the hyperlink in the info panel. */ private static final String INFO_DIV_LINK = "_infoLinkDiv"; /** * Ids that are appended for the spans that are present inside the * hyperlink */ private static final String LEFT_BOTTOM = "_leftBottom_"; private static final String LEFT_TOP = "_leftTop_"; private static final String RIGHT_BOTTOM = "_rightBottom_"; private static final String RIGHT_TOP = "_rightTop_"; private static final String RIGHT_BORDER = "_rightBorder_"; private static final String LINK_TEXT = "_linkText_"; /** *Info icon image link for the task. */ private ImageHyperlink ihk; /** *Spacer image used while rendering a toggle panel. */ private Icon spacer; /** Creates a new instance of TaskRenderer */ public CommonTaskRenderer() { } @Override public boolean getRendersChildren() { return true; } /** * Render a common task. * * @param context The current FacesContext * @param component The CommonTask object to render * @param writer The current ResponseWriter * * @exception IOException if an input/output error occurs */ @Override protected void renderEnd(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { if (context == null || component == null) { throw new NullPointerException(); } CommonTask task = (CommonTask) component; boolean info = false; if (!task.isRendered()) { return; } // The common task component should come inside either a common task group // component or inside a common tasks section component. if (!(task.getParent() instanceof CommonTasksGroup || task.getParent() instanceof CommonTasksSection)) { return; } Theme theme = ThemeUtilities.getTheme(context); UIComponent comp = task.getTaskAction(); String compId = task.getClientId(context); writer.startElement(HTMLElements.DIV, task); writer.writeAttribute(HTMLAttributes.ID, task.getClientId(context), HTMLAttributes.ID); // NOI18N String styles = RenderingUtilities.getStyleClasses(context, task, theme.getStyleClass(ThemeStyles.CTS_TASK)); writer.writeAttribute(HTMLAttributes.CLASS, styles, HTMLAttributes.CLASS); // NOI18N styles = task.getStyle(); if (styles != null) { writer.writeAttribute(HTMLAttributes.STYLE, styles, HTMLAttributes.STYLE); } writer.startElement(HTMLElements.TABLE, task); writer.writeAttribute(HTMLAttributes.BORDER, "0", HTMLAttributes.BORDER); writer.writeAttribute(HTMLAttributes.CELLSPACING, "0", HTMLAttributes.CELLSPACING); writer.writeAttribute(HTMLAttributes.CELLPADDING, "0", HTMLAttributes.CELLPADDING); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_BACKGROUND), HTMLAttributes.CLASS); writer.startElement(HTMLElements.TR, component); // If no facet has been defined, render the default taskAction. if (comp == null) { comp = task; } renderActionItem(comp, task, context, theme, writer); String infoText = task.getInfoText(); String infoTitle = task.getInfoTitle(); UIComponent facet = task.getInfoPanel(); if (facet != null || infoText != null || infoTitle != null) { renderInfoIcon(task, theme, context, writer); renderInfoText(task, theme, context, writer, infoText, infoTitle, facet); } else { renderPlaceHolderImage(task, theme, context, writer); } writer.endElement(HTMLElements.TR); writer.endElement(HTMLElements.TABLE); writer.endElement(HTMLElements.DIV); } /** * Renders the action item for a task. * * @param context The current FacesContext * @param component The action object to render * @param writer The current ResponseWriter * @param theme The theme used for the object */ protected void renderActionItem(UIComponent component, UIComponent task, FacesContext context, Theme theme, ResponseWriter writer) throws IOException { writer.startElement(HTMLElements.TD, component); writer.writeAttribute(HTMLAttributes.WIDTH, "2%", HTMLAttributes.WIDTH); writer.writeAttribute(HTMLAttributes.VALIGN, "bottom", HTMLAttributes.VALIGN); // NOI18N writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_LEFT), null); spacer = ThemeUtilities.getIcon(theme, ThemeImages.CTS_SPACER_IMAGE); spacer.setParent(task); spacer.setId(SPACER_IMAGE); RenderingUtilities.renderComponent(spacer, context); writer.endElement(HTMLElements.TD); writer.startElement(HTMLElements.TD, component); writer.writeAttribute(HTMLAttributes.WIDTH, "100%", HTMLAttributes.WIDTH); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_CENTER), HTMLAttributes.CLASS); // NOI18N // If no facet is defined, render the default taskAction. // Else, render the component that has been specified in the fact. if (component instanceof CommonTask) { renderDefaultTaskAction((CommonTask) component, writer, context, theme); } else { RenderingUtilities.renderComponent(component, context); } writer.endElement(HTMLElements.TD); } /** *Renders an placeholder image if no toggled information panel *comes up. * @param context The current FacesContext * @param component The commonTask object * @param writer The current ResponseWriter * @param theme The theme used for the object */ protected void renderPlaceHolderImage(UIComponent component, Theme theme, FacesContext context, ResponseWriter writer) throws IOException { writer.startElement(HTMLElements.TD, component); writer.writeAttribute(HTMLAttributes.WIDTH, "3%", HTMLAttributes.WIDTH); writer.writeAttribute(HTMLAttributes.ALIGN, "right", HTMLAttributes.ALIGN); // NOI18N writer.writeAttribute(HTMLAttributes.VALIGN, "top", HTMLAttributes.VALIGN); // NOI18N writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_RIGHT), HTMLAttributes.CLASS); // NOI18N String themeIcon = ThemeImages.CTS_RIGHT_TOGGLE_EMPTY; Icon icon = ThemeUtilities.getIcon(theme, themeIcon); icon.setParent(component); icon.setId(TOGGLE_IMAGE); // NOI18N RenderingUtilities.renderComponent(icon, context); writer.endElement(HTMLElements.TD); } /** *Render an info icon alongside the task. Clicking on this would *open a pane which contains information about the task. * @param context The current FacesContext * @param component The commonTask object * @param writer The current ResponseWriter * @param theme The theme used for the object */ protected void renderInfoIcon(UIComponent component, Theme theme, FacesContext context, ResponseWriter writer) throws IOException { writer.startElement(HTMLElements.TD, component); writer.writeAttribute(HTMLAttributes.WIDTH, "3%", HTMLAttributes.WIDTH); writer.writeAttribute(HTMLAttributes.ALIGN, "right", HTMLAttributes.ALIGN); // NOI18N writer.writeAttribute(HTMLAttributes.VALIGN, "top", HTMLAttributes.VALIGN); // NOI18N writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_RIGHT), HTMLAttributes.CLASS); // NOI18N ihk = new ImageHyperlink(); String themeIcon = null; themeIcon = ThemeImages.CTS_RIGHT_TOGGLE; ihk.setId(TOGGLE_IMAGE); // NOI18N ihk.setIcon(themeIcon); ihk.setParent(component); ihk.setToolTip(theme.getMessage(INFO_IMAGE_TOOLTIP)); ihk.setUrl("#"); RenderingUtilities.renderComponent(ihk, context); writer.endElement(HTMLElements.TD); } /** * Renders the info panel for the task * @param context The current FacesContext * @param task The commonTask object * @param writer The current ResponseWriter * @param theme The theme used for the object */ protected void renderInfoText(CommonTask task, Theme theme, FacesContext context, ResponseWriter writer, String infoText, String infoTitle, UIComponent facet) throws IOException { StringBuffer sb; ImageHyperlink close = new ImageHyperlink(); // Start rendering the info menu.. writer.startElement(HTMLElements.DIV, task); writer.writeAttribute(HTMLAttributes.ID, task.getClientId(context) + INFO_DIV, HTMLAttributes.ID);// NOI18N sb = new StringBuffer(); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_INFOPANEL) + " " + theme.getStyleClass(ThemeStyles.HIDDEN), HTMLAttributes.CLASS); // NOI18N writer.startElement(HTMLElements.DIV, task); // NOI18N writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_INFOPANEL_CLOSE), HTMLAttributes.CLASS); close.setParent(task); close.setId(CLOSE_IMAGE); // NOI18N close.setToolTip(theme.getMessage(CLOSE_IMAGE_TOOLTIP)); close.setUrl("#"); if (close.getParent() == null) { close.setParent(task); } close.setIcon(ThemeImages.CTS_PANEL_CLOSE); RenderingUtilities.renderComponent(close, context); writer.endElement(HTMLElements.DIV); writer.startElement(HTMLElements.P, task); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_INFO), HTMLAttributes.CLASS); // If the infoPanel facet exists then use it. // instead of the stuff that is given in the tag attribute. if (facet == null) { writer.startElement(HTMLElements.SPAN, task); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_HEADER), HTMLAttributes.CLASS); if (infoTitle != null) { writer.write(infoTitle); } writer.endElement(HTMLElements.SPAN); writer.startElement(HTMLElements.SPAN, task); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_CONTENT), HTMLAttributes.CLASS); if (infoText != null) { writer.write(infoText); } writer.endElement(HTMLElements.SPAN); } else { RenderingUtilities.renderComponent(facet, context); } writer.endElement(HTMLElements.P); facet = task.getInfoLink(); // Check for the existence of an infoLink facet. if (facet != null) { renderBottomInfoPanel(task, facet, writer, theme, context); } writer.endElement(HTMLElements.DIV); sb = new StringBuffer(); UIComponent section = task.getParent(); if (section instanceof CommonTasksGroup && section.getParent() instanceof CommonTasksSection) { section = section.getParent(); } try { JSONObject json = getJSONProperties(context, theme, task, close, section); sb.append(JavaScriptUtilities.getDomNode(context, section)).append(".addCommonTask(").append(json.toString(JavaScriptUtilities.INDENT_FACTOR)).append(");\n"); //NOI18N JavaScriptUtilities.renderJavaScript(task, writer, sb.toString()); } catch (JSONException e) { e.printStackTrace(); } writer.write("\n"); // NOI18N } /** * Renders the bottom section of the infoPanel * @param task The common task component * @param facet The component to be rendered at the bottom of the info panel. * @param writer The response writer * @param context Faces context * @param theme Theme used for the object */ protected void renderBottomInfoPanel(UIComponent task, UIComponent facet, ResponseWriter writer, Theme theme, FacesContext context) throws IOException { writer.startElement(HTMLElements.P, task); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TASK_MORE), HTMLAttributes.CLASS);// NOI18N writer.startElement(HTMLElements.IMG, task); writer.writeAttribute(HTMLAttributes.BORDER, "0", HTMLAttributes.BORDER); writer.writeAttribute(HTMLAttributes.SRC, theme.getImagePath(ThemeImages.HREF_LINK), HTMLAttributes.SRC); writer.endElement(HTMLElements.IMG); RenderingUtilities.renderComponent(facet, context); writer.endElement(HTMLElements.P); } protected JSONObject getJSONProperties(FacesContext context, Theme theme, UIComponent component, ImageHyperlink close, UIComponent section) throws IOException, JSONException { StringBuffer tmp = new StringBuffer(); tmp.append(ihk.getClientId(context)).append(":").append(ihk.getId()).append("_image"); JSONObject json = new JSONObject(); // common task id json.put("commonTaskId", component.getClientId(context)) // id of the close link that closes the info panel. .put("closeId", close.getClientId(context)) // id of the spacer image used for determining the info panel position .put("spacerId", SPACER_IMAGE) // id of the displayed "i" image .put("infoIconId", tmp.toString()) // id of the info panel div's prefix. .put("infoPanelVar", INFO_DIV) //id of the "i" link image .put("imageLinkId", ihk.getClientId(context)); return json; } /** * Render a common task element. * * @param context The current FacesContext * @param component The CommonTask object to render * @param writer The current ResponseWriter * * @exception IOException if an input/output error occurs */ @Override protected void renderStart(FacesContext context, UIComponent component, ResponseWriter writer) throws IOException { } protected void renderDefaultTaskAction(CommonTask task, ResponseWriter writer, FacesContext context, Theme theme) throws IOException { String onclick = task.getOnClick(); String target = task.getTarget(); String tooltip = task.getToolTip(); writer.startElement(HTMLElements.A, task); writer.writeAttribute(HTMLAttributes.ID, task.getClientId(context) + COMMONTASK_LINK, HTMLAttributes.ID); UIComponent form = Util.getForm(context, task); if (form != null) { String formClientId = form.getClientId(context); StringBuffer buff = new StringBuffer(200); if (onclick != null) { buff.append(onclick); if (!onclick.endsWith(";")) { //NOI18N buff.append(";"); //NOI18N } } buff.append("return ") //NOI18N .append(JavaScriptUtilities.getModuleName( "hyperlink.submit")) //NOI18N .append("(this, ") //NOI18N .append("'") //NOI18N .append(formClientId).append("'") //NOI18N .append(", "); //NOI18N boolean didOnce = false; Iterator kids = task.getChildren().iterator(); while (kids.hasNext()) { UIComponent kid = (UIComponent) kids.next(); if (!(kid instanceof UIParameter)) { continue; } if (!didOnce) { buff.append("new Array("); } String name = (String) kid.getAttributes().get("name"); //NOI18N String value = (String) kid.getAttributes().get("value"); //NOI18N //add to map for later use. if (!didOnce) { buff.append("'"); } else { buff.append(",'"); } buff.append(name); buff.append("','"); buff.append(value); buff.append("'"); //NOI18N didOnce = true; } if (!didOnce) { buff.append("null"); } else { buff.append(")"); } buff.append(");"); writer.writeAttribute(HTMLAttributes.ONCLICK, buff.toString(), null); writer.writeAttribute(HTMLAttributes.HREF, "#", null); //NOI18N writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_TEXT_BGROUND), null); } if (null != target) { writer.writeAttribute(HTMLAttributes.TARGET, target, null); //NOI18N } if (null != tooltip) { writer.writeAttribute(HTMLAttributes.TITLE, tooltip, null); //NOI18N } addIntegerAttributes(context, task, writer, integerAttributes); addStringAttributes(context, task, writer, stringAttributes); // We need to display these styles only at runtime. // They do not lend themselves very well at design time. if (!Beans.isDesignTime()) { renderStyles(task, writer, theme, context); } // Used for rendering the image along with the text. ImageComponent img = null; // The icon attribute gets preference over the imageURL attribute. // So, first check if the icon attribute is set. If not, check // whether the imageUrl attribute is set and set the image component's String icon = task.getIcon(); // properties accordingly. if (icon != null) { img = ThemeUtilities.getIcon(theme, icon); } else { img = new ImageComponent(); icon = task.getImageUrl(); if (icon != null) { img.setUrl(icon); int dim = task.getImageHeight(); if (dim > 0) { img.setHeight(dim); } dim = task.getImageWidth(); if (dim > 0) { img.setWidth(dim); } } } // Used for rendering the image along with the text. img.setId(task.getId() + "_img"); img.setToolTip(theme.getMessage(OVERVIEW_IMAGE_TOOLTIP)); img.setStyleClass(theme.getStyleClass(ThemeStyles.CTS_TASK_BULLET)); writer.startElement(HTMLElements.SPAN, task); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_PADDING), null); writer.writeAttribute(HTMLAttributes.ID, task.getClientId(context) + LINK_TEXT, null); if (img.getUrl() != null) { RenderingUtilities.renderComponent(img, context); } String text = ConversionUtilities.convertValueToString(task, task.getText()); if (text != null) { writer.write(text); } writer.endElement(HTMLElements.SPAN); writer.endElement(HTMLElements.A); } protected void renderStyles(CommonTask component, ResponseWriter writer, Theme theme, FacesContext context) throws IOException { String clientId = component.getClientId(context); writer.startElement(HTMLElements.SPAN, component); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_LEFT_BOTTOM), null); writer.writeAttribute(HTMLAttributes.ID, clientId + LEFT_BOTTOM, null); writer.endElement(HTMLElements.SPAN); writer.startElement(HTMLElements.SPAN, component); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_LEFT_TOP), null); writer.writeAttribute(HTMLAttributes.ID, clientId + LEFT_TOP, null); writer.endElement(HTMLElements.SPAN); writer.startElement(HTMLElements.SPAN, component); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_RIGHT_BOTTOM), null); writer.writeAttribute(HTMLAttributes.ID, clientId + RIGHT_BOTTOM, null); writer.endElement(HTMLElements.SPAN); writer.startElement(HTMLElements.SPAN, component); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_RIGHT_TOP), null); writer.writeAttribute(HTMLAttributes.ID, clientId + RIGHT_TOP, null); writer.endElement(HTMLElements.SPAN); writer.startElement(HTMLElements.SPAN, component); writer.writeAttribute(HTMLAttributes.CLASS, theme.getStyleClass(ThemeStyles.CTS_RIGHT_BORDER), null); writer.writeAttribute(HTMLAttributes.ID, clientId + RIGHT_BORDER, null); writer.endElement(HTMLElements.SPAN); } /** * Decode the submitted component. * */ @Override public void decode(FacesContext context, UIComponent component) { // Enforce NPE requirements in the Javadocs if ((context == null) || (component == null)) { throw new NullPointerException(); } CommonTask link = (CommonTask) component; StringBuffer paramId = new StringBuffer(); String clientId = component.getClientId(context); paramId.append(clientId).append(COMMONTASK_LINK).append("_submittedField"); String value = (String) context.getExternalContext().getRequestParameterMap(). get(paramId.toString()); if ((value == null) || !value.equals(clientId + COMMONTASK_LINK)) { return; } //add the event to the queue so we know that a command happened. //this should automatically take care of actionlisteners and actions link.queueEvent(new ActionEvent(link)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy