org.apache.myfaces.renderkit.html.ext.HtmlMessageRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.myfaces.renderkit.html.ext.HtmlMessageRenderer.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.myfaces.renderkit.html.ext;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;
import javax.faces.component.ValueHolder;
import javax.faces.component.behavior.ClientBehavior;
import javax.faces.component.behavior.ClientBehaviorHolder;
import javax.faces.component.html.HtmlOutputLabel;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.component.html.ext.HtmlMessage;
import org.apache.myfaces.component.html.ext.HtmlMessages;
import org.apache.myfaces.shared_tomahawk.renderkit.RendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlMessageRendererBase;
import org.apache.myfaces.shared_tomahawk.renderkit.html.HtmlRendererUtils;
import org.apache.myfaces.shared_tomahawk.renderkit.html.util.ResourceUtils;

/**
 * @JSFRenderer
 *   renderKitId = "HTML_BASIC"
 *   family = "javax.faces.Message"
 *   type = "org.apache.myfaces.Message"
 * 
 * @author Manfred Geiler (latest modification by $Author: lu4242 $)
 * @version $Revision: 940144 $ $Date: 2010-05-01 20:39:32 -0500 (Sb, 01 May 2010) $
 */
public class HtmlMessageRenderer extends HtmlMessageRendererBase {
    private static final Log log = LogFactory.getLog(HtmlMessageRenderer.class);

    private static final String OUTPUT_LABEL_MAP = HtmlMessageRenderer.class.getName() + ".OUTPUT_LABEL_MAP";

    @Override
    public void decode(FacesContext context, UIComponent component) {
        super.decode(context, component);

        HtmlRendererUtils.decodeClientBehaviors(context, component);
    }

    public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException {
        super.encodeEnd(facesContext, component); //check for NP

        Map<String, List<ClientBehavior>> behaviors = null;
        if (component instanceof ClientBehaviorHolder) {
            behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
            if (!behaviors.isEmpty()) {
                ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, facesContext.getResponseWriter());
            }
        }

        boolean forceSpan = false;
        if (component instanceof HtmlMessage && ((HtmlMessage) component).getForceSpan()) {
            forceSpan = true;
        }

        renderMessage(facesContext, component, forceSpan, true);

        /*
        if (component instanceof HtmlMessage
            && ((HtmlMessage)component).getForceSpan())
        {
        String forAttr = getFor(component);
        HtmlMessage htmlMessage = (HtmlMessage) component;
            
        UIComponent forComponent = component.findComponent(forAttr);
            
        if (forComponent != null)
        {
            String forCompclientId = forComponent.getClientId(facesContext);
            
            ResponseWriter writer = facesContext.getResponseWriter();
            writer.startElement(HTML.SPAN_ELEM, null);
            writer.writeAttribute(HTML.ID_ATTR, forCompclientId + "_msgFor", null);
            if(htmlMessage.getStyleClass()!=null)
            writer.writeAttribute(HTML.CLASS_ATTR,htmlMessage.getStyleClass(),null);
            if(htmlMessage.getStyle()!=null)
            writer.writeAttribute(HTML.STYLE_ATTR,htmlMessage.getStyle(),null);
            writer.endElement(HTML.SPAN_ELEM);
        }
        }*/
    }

    protected String getSummary(FacesContext facesContext, UIComponent message, FacesMessage facesMessage,
            String msgClientId) {
        String msgSummary = facesMessage.getSummary();
        if (msgSummary == null)
            return null;

        String inputLabel = null;
        if (msgClientId != null)
            inputLabel = findInputLabel(facesContext, msgClientId);
        if (inputLabel == null)
            inputLabel = "";

        if (((message instanceof HtmlMessages && ((HtmlMessages) message).isReplaceIdWithLabel())
                || (message instanceof HtmlMessage && ((HtmlMessage) message).isReplaceIdWithLabel()))
                && inputLabel.length() != 0)
            msgSummary = msgSummary.replaceAll(findInputId(facesContext, msgClientId), inputLabel);

        String summaryFormat;
        if (message instanceof HtmlMessage) {
            summaryFormat = ((HtmlMessage) message).getSummaryFormat();
        } else {
            summaryFormat = (String) message.getAttributes().get("summaryFormat");
        }

        if (summaryFormat == null)
            return msgSummary;

        MessageFormat format = new MessageFormat(summaryFormat, facesContext.getViewRoot().getLocale());

        return format.format(new Object[] { msgSummary, inputLabel });
    }

    protected String getDetail(FacesContext facesContext, UIComponent message, FacesMessage facesMessage,
            String msgClientId) {
        String msgDetail = facesMessage.getDetail();
        if (msgDetail == null)
            return null;

        String inputLabel = null;
        if (msgClientId != null)
            inputLabel = findInputLabel(facesContext, msgClientId);
        if (inputLabel == null)
            inputLabel = "";

        if (((message instanceof HtmlMessages && ((HtmlMessages) message).isReplaceIdWithLabel())
                || (message instanceof HtmlMessage && ((HtmlMessage) message).isReplaceIdWithLabel()))
                && inputLabel.length() != 0)
            msgDetail = msgDetail.replaceAll(findInputId(facesContext, msgClientId), inputLabel);

        String detailFormat;
        if (message instanceof HtmlMessage) {
            detailFormat = ((HtmlMessage) message).getDetailFormat();
        } else {
            detailFormat = (String) message.getAttributes().get("detailFormat");
        }

        if (detailFormat == null)
            return msgDetail;

        MessageFormat format = new MessageFormat(detailFormat, facesContext.getViewRoot().getLocale());
        return format.format(new Object[] { msgDetail, inputLabel });
    }

    public static String findInputLabel(FacesContext facesContext, String inputClientId) {
        Map<String, MessageLabelInfo> outputLabelMap = getOutputLabelMap(facesContext);
        MessageLabelInfo info = ((MessageLabelInfo) outputLabelMap.get(inputClientId));

        if (info == null) {
            UIComponent comp = facesContext.getViewRoot().findComponent(inputClientId);

            UIComponent parent = comp;

            while (parent != null && !((parent = parent.getParent()) instanceof UIColumn))
                ;

            if (parent != null) {
                UIColumn column = (UIColumn) parent;

                if (column.getHeader() != null) {
                    UIComponent header = column.getHeader();

                    return getComponentText(facesContext, header);
                }
            }
        }

        return info == null ? null : info.getText(facesContext);
    }

    public static String findInputId(FacesContext facesContext, String inputClientId) {
        Map<String, MessageLabelInfo> outputLabelMap = getOutputLabelMap(facesContext);
        MessageLabelInfo info = ((MessageLabelInfo) outputLabelMap.get(inputClientId));

        UIComponent comp = null;

        if (info == null) {
            comp = facesContext.getViewRoot().findComponent(inputClientId);
        } else {
            comp = info.getForComponent();
        }

        if (comp == null)
            return null;

        if (inputClientId.contains(NamingContainer.SEPARATOR_CHAR + "")) {
            // Full client id is being used
            //
            return comp.getClientId(facesContext);
        } else {
            // Id is being used (or client id is one level deep, which means it doesn't matter)
            //
            return comp.getId();
        }
    }

    /**
     * @param facesContext
     * @return a Map that reversely maps clientIds of components to their
     *         corresponding OutputLabel component
     */
    @SuppressWarnings("unchecked")
    private static Map<String, MessageLabelInfo> getOutputLabelMap(FacesContext facesContext) {
        Map<String, MessageLabelInfo> map = (Map<String, MessageLabelInfo>) facesContext.getExternalContext()
                .getRequestMap().get(OUTPUT_LABEL_MAP);
        if (map == null) {
            map = new HashMap<String, MessageLabelInfo>();
            createOutputLabelMap(facesContext, facesContext.getViewRoot(), map);
            facesContext.getExternalContext().getRequestMap().put(OUTPUT_LABEL_MAP, map);
        }
        return map;
    }

    private static void createOutputLabelMap(FacesContext facesContext, UIComponent root,
            Map<String, MessageLabelInfo> map) {
        for (Iterator<UIComponent> it = root.getFacetsAndChildren(); it.hasNext();) {
            UIComponent child = (UIComponent) it.next();
            if (child instanceof HtmlOutputLabel) {
                String forAttr = ((HtmlOutputLabel) child).getFor();
                if (forAttr != null) {
                    UIComponent input = child.findComponent(forAttr);
                    if (input == null) {
                        log.warn("Unable to find component '" + forAttr + "' (calling findComponent on component '"
                                + child.getClientId(facesContext) + "')");
                    } else {
                        if (child.getValueExpression("value") == null) {
                            // If the child uses a ValueExpression, do not evaluate the text
                            // right now. When getText(FacesContext) is called, do it there.
                            map.put(input.getClientId(facesContext), new MessageDefferedLabelInfo(input, child));
                        } else {
                            map.put(input.getClientId(facesContext), new MessageTextLabelInfo(input,
                                    getComponentText(facesContext, (HtmlOutputLabel) child)));
                        }
                    }
                }
            } else {
                createOutputLabelMap(facesContext, child, map);
            }
        }
    }

    private static String getComponentText(FacesContext facesContext, UIComponent component) {
        String text = null;

        if (component instanceof ValueHolder) {
            text = RendererUtils.getStringValue(facesContext, component);
        }

        if (text == null || text.length() < 1) {
            StringBuffer buf = new StringBuffer();
            List<UIComponent> li = component.getChildren();

            for (int i = 0; i < li.size(); i++) {
                UIComponent child = (UIComponent) li.get(i);

                if (child instanceof HtmlOutputText) {
                    String str = RendererUtils.getStringValue(facesContext, child);

                    if (str != null)
                        buf.append(str);
                }
            }

            text = buf.toString();
        }
        return text;
    }

    public static interface MessageLabelInfo {
        public UIComponent getForComponent();

        public String getText(FacesContext context);
    }

    public final static class MessageTextLabelInfo implements MessageLabelInfo {
        private final UIComponent _forComponent;
        private final String _text;

        public MessageTextLabelInfo(final UIComponent forComponent, final String text) {
            _forComponent = forComponent;
            _text = text;
        }

        public UIComponent getForComponent() {
            return _forComponent;
        }

        public String getText(FacesContext context) {
            return _text;
        }
    }

    public final static class MessageDefferedLabelInfo implements MessageLabelInfo {
        private final UIComponent _forComponent;
        private final UIComponent _labelComponent;
        private String _text;

        public MessageDefferedLabelInfo(final UIComponent forComponent, final UIComponent labelComponent) {
            _forComponent = forComponent;
            _labelComponent = labelComponent;
        }

        public UIComponent getForComponent() {
            return _forComponent;
        }

        public String getText(FacesContext context) {
            if (_text == null) {
                _text = getComponentText(context, (HtmlOutputLabel) _labelComponent);
            }
            return _text;
        }
    }
}