View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.renderkit.html;
20  
21  import java.io.IOException;
22  import java.text.MessageFormat;
23  import java.util.ArrayList;
24  import java.util.List;
25  import java.util.logging.Level;
26  import java.util.logging.Logger;
27  
28  import javax.faces.component.UIComponent;
29  import javax.faces.component.UIOutput;
30  import javax.faces.component.UIParameter;
31  import javax.faces.component.UIViewRoot;
32  import javax.faces.component.html.HtmlOutputFormat;
33  import javax.faces.context.FacesContext;
34  import javax.faces.context.ResponseWriter;
35  
36  import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFRenderer;
37  import org.apache.myfaces.shared.renderkit.JSFAttr;
38  import org.apache.myfaces.shared.renderkit.RendererUtils;
39  import org.apache.myfaces.shared.renderkit.html.CommonPropertyConstants;
40  import org.apache.myfaces.shared.renderkit.html.CommonPropertyUtils;
41  import org.apache.myfaces.shared.renderkit.html.HTML;
42  import org.apache.myfaces.shared.renderkit.html.HtmlRenderer;
43  import org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils;
44  
45  /**
46   * 
47   * @author Manfred Geiler (latest modification by $Author$)
48   * @author Thomas Spiegl
49   * @version $Revision$ $Date$
50   */
51  @JSFRenderer(renderKitId = "HTML_BASIC", family = "javax.faces.Output", type = "javax.faces.Format")
52  public class HtmlFormatRenderer extends HtmlRenderer
53  {
54      private static final Logger log = Logger.getLogger(HtmlFormatRenderer.class.getName());
55  
56      private static final Object[] EMPTY_ARGS = new Object[0];
57      
58      @Override
59      protected boolean isCommonPropertiesOptimizationEnabled(FacesContext facesContext)
60      {
61          return true;
62      }
63  
64      @Override
65      protected boolean isCommonEventsOptimizationEnabled(FacesContext facesContext)
66      {
67          return true;
68      }
69  
70      @Override
71      public void encodeBegin(FacesContext facesContext, UIComponent uiComponent) throws IOException
72      {
73      }
74  
75      @Override
76      public void encodeChildren(FacesContext facescontext, UIComponent uicomponent) throws IOException
77      {
78      }
79  
80      @Override
81      public void encodeEnd(FacesContext facesContext, UIComponent component) throws IOException
82      {
83          RendererUtils.checkParamValidity(facesContext, component, UIOutput.class);
84  
85          String text = getOutputFormatText(facesContext, component);
86          boolean escape;
87          if (component instanceof HtmlOutputFormat)
88          {
89              escape = ((HtmlOutputFormat) component).isEscape();
90          }
91          else
92          {
93              escape = RendererUtils.getBooleanAttribute(component, JSFAttr.ESCAPE_ATTR, true);
94          }
95          if (text != null)
96          {
97              ResponseWriter writer = facesContext.getResponseWriter();
98              boolean span = false;
99  
100             if (isCommonPropertiesOptimizationEnabled(facesContext))
101             {
102                 long commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
103                 
104                 if ( (commonPropertiesMarked & ~(CommonPropertyConstants.ESCAPE_PROP)) > 0)
105                 {
106                     span = true;
107                     writer.startElement(HTML.SPAN_ELEM, component);
108                     HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
109                 }
110                 else if (CommonPropertyUtils.isIdRenderingNecessary(component))
111                 {
112                     span = true;
113                     writer.startElement(HTML.SPAN_ELEM, component);
114                     writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext), null);
115                 }
116                 
117                 CommonPropertyUtils.renderUniversalProperties(writer, commonPropertiesMarked, component);
118                 CommonPropertyUtils.renderStyleProperties(writer, commonPropertiesMarked, component);
119             }
120             else
121             {
122                 if(component.getId()!=null && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
123                 {
124                     span = true;
125     
126                     writer.startElement(HTML.SPAN_ELEM, component);
127     
128                     HtmlRendererUtils.writeIdIfNecessary(writer, component, facesContext);
129     
130                     HtmlRendererUtils.renderHTMLAttributes(writer, component, HTML.COMMON_PASSTROUGH_ATTRIBUTES);
131     
132                 }
133                 else
134                 {
135                     span = HtmlRendererUtils.renderHTMLAttributesWithOptionalStartElement(writer,component,
136                             HTML.SPAN_ELEM,HTML.COMMON_PASSTROUGH_ATTRIBUTES);
137                 }
138             }
139 
140             if (escape)
141             {
142                 if (log.isLoggable(Level.FINE))
143                 {
144                     log.fine("renderOutputText writing '" + text + "'");
145                 }
146                 writer.writeText(text, org.apache.myfaces.shared.renderkit.JSFAttr.VALUE_ATTR);
147             }
148             else
149             {
150                 writer.write(text);
151             }
152 
153             if(span)
154             {
155                 writer.endElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM);
156             }
157         }
158     }
159 
160     private String getOutputFormatText(FacesContext facesContext, UIComponent htmlOutputFormat)
161     {
162         String pattern = RendererUtils.getStringValue(facesContext, htmlOutputFormat);
163         Object[] args;
164         if (htmlOutputFormat.getChildCount() == 0)
165         {
166             args = EMPTY_ARGS;
167         }
168         else
169         {
170             List<Object> argsList = null;
171             
172             if (htmlOutputFormat.getChildCount() > 0)
173             {
174                 List<UIParameter> validParams = HtmlRendererUtils.getValidUIParameterChildren(
175                         facesContext, htmlOutputFormat.getChildren(), false, false, false);
176                 for (int i = 0, size = validParams.size(); i < size; i++)
177                 {
178                     UIParameter param = validParams.get(i);
179                     if (argsList == null)
180                     {
181                         argsList = new ArrayList<>();
182                     }
183                     argsList.add(param.getValue());
184                 }
185             }
186             
187             if (argsList != null)
188             {
189                 args = argsList.toArray(new Object[argsList.size()]);
190             }
191             else
192             {
193                 args = EMPTY_ARGS;
194             }
195         }
196 
197         MessageFormat format = new MessageFormat(pattern, facesContext.getViewRoot().getLocale());
198         try
199         {
200             return format.format(args);
201         }
202         catch (Exception e)
203         {
204             log.log(Level.SEVERE, "Error formatting message of component "
205                                   + htmlOutputFormat.getClientId(facesContext));
206             return "";
207         }
208     }
209 
210 }