Coverage Report - org.apache.myfaces.shared.renderkit.html.HtmlFormRendererBase
 
Classes in this File Line Coverage Branch Coverage Complexity
HtmlFormRendererBase
0%
0/115
0%
0/48
2.667
 
 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.shared.renderkit.html;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.HashSet;
 23  
 import java.util.List;
 24  
 import java.util.Map;
 25  
 import java.util.Set;
 26  
 
 27  
 import javax.faces.application.ViewHandler;
 28  
 import javax.faces.component.UIComponent;
 29  
 import javax.faces.component.UIForm;
 30  
 import javax.faces.component.behavior.ClientBehavior;
 31  
 import javax.faces.component.behavior.ClientBehaviorHolder;
 32  
 import javax.faces.component.html.HtmlForm;
 33  
 import javax.faces.context.FacesContext;
 34  
 import javax.faces.context.ResponseWriter;
 35  
 
 36  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 37  
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 38  
 import org.apache.myfaces.shared.renderkit.html.util.ResourceUtils;
 39  
 
 40  0
 public class HtmlFormRendererBase
 41  
         extends HtmlRenderer
 42  
 {
 43  
     //private static final Log log = LogFactory.getLog(HtmlFormRenderer.class);
 44  
     private static final String FORM_TARGET = HTML.FORM_ELEM;
 45  
     private static final String HIDDEN_SUBMIT_INPUT_SUFFIX = "_SUBMIT";
 46  
     private static final String HIDDEN_SUBMIT_INPUT_VALUE = "1";
 47  
 
 48  0
     private static final String HIDDEN_COMMAND_INPUTS_SET_ATTR
 49  
             = UIForm.class.getName() + ".org.apache.myfaces.HIDDEN_COMMAND_INPUTS_SET";
 50  
 
 51  
     private static final String SCROLL_HIDDEN_INPUT = "org.apache.myfaces.SCROLL_HIDDEN_INPUT";
 52  
 
 53  
     public void encodeBegin(FacesContext facesContext, UIComponent component)
 54  
             throws IOException
 55  
     {
 56  0
         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIForm.class);
 57  
 
 58  0
         UIForm htmlForm = (UIForm)component;
 59  
 
 60  0
         ResponseWriter writer = facesContext.getResponseWriter();
 61  0
         String clientId = htmlForm.getClientId(facesContext);
 62  0
         String acceptCharset = getAcceptCharset(facesContext, htmlForm);
 63  0
         String actionURL = getActionUrl(facesContext, htmlForm);
 64  0
         String method = getMethod(facesContext, htmlForm);
 65  
 
 66  0
         Map<String, List<ClientBehavior>> behaviors = null;
 67  0
         if (component instanceof ClientBehaviorHolder)
 68  
         {
 69  0
             behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
 70  0
             if (!behaviors.isEmpty())
 71  
             {
 72  0
                 ResourceUtils.renderDefaultJsfJsInlineIfNecessary(facesContext, writer);
 73  
             }
 74  
         }
 75  
         
 76  0
         writer.startElement(HTML.FORM_ELEM, htmlForm);
 77  0
         writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 78  0
         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 79  0
         writer.writeAttribute(HTML.METHOD_ATTR, method, null);
 80  0
         if (acceptCharset != null)
 81  
         {
 82  0
             writer.writeAttribute(HTML.ACCEPT_CHARSET_ATTR, acceptCharset, null);
 83  
         }
 84  0
         String encodedActionURL = facesContext.getExternalContext().encodeActionURL(actionURL);
 85  
         
 86  0
         writer.writeURIAttribute(HTML.ACTION_ATTR,
 87  
                 encodedActionURL,
 88  
                 null);
 89  
         
 90  0
         if (htmlForm instanceof ClientBehaviorHolder)
 91  
         {
 92  0
             behaviors = ((ClientBehaviorHolder) htmlForm).getClientBehaviors();
 93  0
             if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
 94  
             {
 95  0
                 CommonPropertyUtils.renderEventProperties(writer, 
 96  
                         CommonPropertyUtils.getCommonPropertiesMarked(htmlForm), htmlForm);
 97  
             }
 98  
             else
 99  
             {
 100  0
                 if (isCommonEventsOptimizationEnabled(facesContext))
 101  
                 {
 102  0
                     CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
 103  
                            CommonPropertyUtils.getCommonPropertiesMarked(htmlForm),
 104  
                            CommonEventUtils.getCommonEventsMarked(htmlForm), htmlForm, behaviors);
 105  
                 }
 106  
                 else
 107  
                 {
 108  0
                     HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, htmlForm, behaviors);
 109  
                 }
 110  
             }
 111  0
             if (isCommonPropertiesOptimizationEnabled(facesContext))
 112  
             {
 113  0
                 CommonPropertyUtils.renderCommonPassthroughPropertiesWithoutEvents(writer, 
 114  
                         CommonPropertyUtils.getCommonPropertiesMarked(component), component);
 115  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_ATTRIBUTES);
 116  
             }
 117  
             else
 118  
             {
 119  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, 
 120  
                         HTML.FORM_PASSTHROUGH_ATTRIBUTES_WITHOUT_EVENTS);
 121  
             }
 122  
         }
 123  
         else
 124  
         {
 125  0
             if (isCommonPropertiesOptimizationEnabled(facesContext))
 126  
             {
 127  0
                 CommonPropertyUtils.renderCommonPassthroughProperties(writer, 
 128  
                         CommonPropertyUtils.getCommonPropertiesMarked(component), component);
 129  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_ATTRIBUTES);
 130  
             }
 131  
             else
 132  
             {
 133  0
                 HtmlRendererUtils.renderHTMLAttributes(writer, htmlForm, HTML.FORM_PASSTHROUGH_ATTRIBUTES);
 134  
             }
 135  
         }
 136  
 
 137  0
         writer.write(""); // force start element tag to be closed
 138  
 
 139  0
         String encodedPartialActionURL =  facesContext.getExternalContext().encodePartialActionURL(actionURL);
 140  
         
 141  0
         if (encodedActionURL != null && encodedPartialActionURL != null
 142  
             && (!encodedActionURL.equals(encodedPartialActionURL)))
 143  
         {
 144  0
             HtmlRendererUtils.renderHiddenInputField(writer, "javax.faces.encodedURL", encodedPartialActionURL);
 145  
         }
 146  
         
 147  
         // not needed in this version as nothing is written to the form tag, but
 148  
         // included for backward compatibility to the 1.1.1 patch (JIRA MYFACES-1276)
 149  
         // However, might be needed in the future
 150  0
         beforeFormElementsStart(facesContext, component);
 151  
         
 152  0
         MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
 153  0
         if (config.isRenderFormViewStateAtBegin())
 154  
         {
 155  0
             renderViewStateAndHiddenFields(facesContext, component);
 156  
         }
 157  
         
 158  0
         afterFormElementsStart(facesContext, component);
 159  0
     }
 160  
 
 161  
     protected String getActionUrl(FacesContext facesContext, UIForm form)
 162  
     {
 163  0
         return getActionUrl(facesContext);
 164  
     }
 165  
 
 166  
     protected String getMethod(FacesContext facesContext, UIForm form)
 167  
     {
 168  0
         return "post";
 169  
     }
 170  
 
 171  
     protected String getAcceptCharset(FacesContext facesContext, UIForm form )
 172  
     {
 173  0
         return (String)form.getAttributes().get( JSFAttr.ACCEPTCHARSET_ATTR );
 174  
     }
 175  
 
 176  
     public void encodeEnd(FacesContext facesContext, UIComponent component)
 177  
             throws IOException
 178  
     {
 179  0
         ResponseWriter writer = facesContext.getResponseWriter();
 180  
 
 181  0
         beforeFormElementsEnd(facesContext, component);
 182  
 
 183  
         //render hidden command inputs
 184  0
         Set set =  (Set) facesContext.getExternalContext().getRequestMap().get(
 185  
                 getHiddenCommandInputsSetName(facesContext, component)); 
 186  0
         if (set != null && !set.isEmpty())
 187  
         {
 188  0
             HtmlRendererUtils.renderHiddenCommandFormParams(writer, set);
 189  
 
 190  
             String target;
 191  0
             if (component instanceof HtmlForm)
 192  
             {
 193  0
                 target = ((HtmlForm)component).getTarget();
 194  
             }
 195  
             else
 196  
             {
 197  0
                 target = (String)component.getAttributes().get(HTML.TARGET_ATTR);
 198  
             }
 199  0
             HtmlRendererUtils.renderClearHiddenCommandFormParamsFunction(writer,
 200  
                                                                          component.getClientId(facesContext),
 201  
                                                                          set,
 202  
                                                                          target);
 203  
         }
 204  
 
 205  0
         MyfacesConfig config = MyfacesConfig.getCurrentInstance(facesContext.getExternalContext());
 206  0
         if (!config.isRenderFormViewStateAtBegin())
 207  
         {
 208  0
             renderViewStateAndHiddenFields(facesContext, component);
 209  
         }
 210  
 
 211  0
         afterFormElementsEnd(facesContext, component);
 212  
         
 213  0
         writer.endElement(HTML.FORM_ELEM);
 214  0
     }
 215  
     
 216  
     protected void renderViewStateAndHiddenFields(FacesContext facesContext, UIComponent component)
 217  
             throws IOException
 218  
     {
 219  0
         ResponseWriter writer = facesContext.getResponseWriter();
 220  
         
 221  
                 //write hidden input to determine "submitted" value on decode
 222  0
         writer.startElement(HTML.INPUT_ELEM, null); // component);
 223  0
         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
 224  0
         writer.writeAttribute(HTML.NAME_ATTR, component.getClientId(facesContext) +
 225  
                                               HIDDEN_SUBMIT_INPUT_SUFFIX, null);
 226  0
         writer.writeAttribute(HTML.VALUE_ATTR, HIDDEN_SUBMIT_INPUT_VALUE, null);
 227  0
         writer.endElement(HTML.INPUT_ELEM);
 228  
 
 229  0
         renderScrollHiddenInputIfNecessary(component, facesContext, writer);
 230  
 
 231  
         //write state marker at the end of the form
 232  
         //Todo: this breaks client-side enabled AJAX components again which are searching for the state
 233  
         //we'll need to fix this
 234  0
         ViewHandler viewHandler = facesContext.getApplication().getViewHandler();
 235  0
         viewHandler.writeState(facesContext);
 236  
 
 237  0
         List<UIComponent> componentResources = facesContext.getViewRoot().getComponentResources(facesContext,
 238  
             FORM_TARGET);
 239  
         
 240  0
         for (int i = 0, size = componentResources.size(); i < size; i++)
 241  
         {
 242  0
            UIComponent child = componentResources.get(i);
 243  0
            child.encodeAll (facesContext);
 244  
         }
 245  0
     }
 246  
 
 247  
     private static String getHiddenCommandInputsSetName(FacesContext facesContext, UIComponent form)
 248  
     {
 249  0
         StringBuilder buf = new StringBuilder(HIDDEN_COMMAND_INPUTS_SET_ATTR.length()+20);
 250  0
         buf.append(HIDDEN_COMMAND_INPUTS_SET_ATTR);
 251  0
         buf.append("_");
 252  0
         buf.append(form.getClientId(facesContext));
 253  0
         return buf.toString();
 254  
     }
 255  
 
 256  
     private static String getScrollHiddenInputName(FacesContext facesContext, UIComponent form)
 257  
     {
 258  0
         StringBuilder buf = new StringBuilder(SCROLL_HIDDEN_INPUT.length()+20);
 259  0
         buf.append(SCROLL_HIDDEN_INPUT);
 260  0
         buf.append("_");
 261  0
         buf.append(form.getClientId(facesContext));
 262  0
         return buf.toString();
 263  
     }
 264  
 
 265  
 
 266  
     public void decode(FacesContext facesContext, UIComponent component)
 267  
     {
 268  0
         org.apache.myfaces.shared.renderkit.RendererUtils.checkParamValidity(facesContext, component, UIForm.class);
 269  
 
 270  
         /*
 271  
         if (HTMLUtil.isDisabled(component))
 272  
         {
 273  
             return;
 274  
         }
 275  
         */
 276  
 
 277  0
         UIForm htmlForm = (UIForm)component;
 278  
 
 279  0
         Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
 280  0
         String submittedValue = (String)paramMap.get(component.getClientId(facesContext) +
 281  
                                                      HIDDEN_SUBMIT_INPUT_SUFFIX);
 282  0
         if (submittedValue != null && submittedValue.equals(HIDDEN_SUBMIT_INPUT_VALUE))
 283  
         {
 284  0
             htmlForm.setSubmitted(true);
 285  
         }
 286  
         else
 287  
         {
 288  0
             htmlForm.setSubmitted(false);
 289  
         }
 290  
         
 291  0
         HtmlRendererUtils.decodeClientBehaviors(facesContext, component);
 292  0
     }
 293  
 
 294  
 
 295  
     public static void addHiddenCommandParameter(FacesContext facesContext, UIComponent form, String paramName)
 296  
     {
 297  0
         Set set = (Set) facesContext.getExternalContext().getRequestMap().get(
 298  
                 getHiddenCommandInputsSetName(facesContext, form));
 299  0
         if (set == null)
 300  
         {
 301  0
             set = new HashSet();
 302  0
             facesContext.getExternalContext().getRequestMap().put(
 303  
                     getHiddenCommandInputsSetName(facesContext, form), set);
 304  
         }
 305  0
         set.add(paramName);
 306  0
     }
 307  
 
 308  
     public static void renderScrollHiddenInputIfNecessary(
 309  
             UIComponent form, FacesContext facesContext, ResponseWriter writer)
 310  
         throws IOException
 311  
     {
 312  0
         if (form == null)
 313  
         {
 314  0
             return;
 315  
         }
 316  
 
 317  0
         if (facesContext.getExternalContext().getRequestMap().get(
 318  
                 getScrollHiddenInputName(facesContext, form)) == null)
 319  
         {
 320  0
             if (MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isAutoScroll())
 321  
             {
 322  0
                 HtmlRendererUtils.renderAutoScrollHiddenInput(facesContext, writer);
 323  
             }
 324  0
             facesContext.getExternalContext().getRequestMap().put(getScrollHiddenInputName(
 325  
                     facesContext, form), Boolean.TRUE);
 326  
         }
 327  0
     }
 328  
 
 329  
     /**
 330  
      * Called before the state and any elements are added to the form tag in the
 331  
      * encodeBegin method
 332  
      */
 333  
     protected void beforeFormElementsStart(FacesContext facesContext, UIComponent component)
 334  
             throws IOException
 335  
     {
 336  
         
 337  0
     }
 338  
 
 339  
     /**
 340  
      * Called after the state and any elements are added to the form tag in the
 341  
      * encodeBegin method
 342  
      */
 343  
     protected void afterFormElementsStart(FacesContext facesContext, UIComponent component)
 344  
             throws IOException
 345  
     {
 346  
         
 347  0
     }
 348  
 
 349  
     /**
 350  
      * Called before the state and any elements are added to the form tag in the
 351  
      * encodeEnd method
 352  
      */
 353  
     protected void beforeFormElementsEnd(FacesContext facesContext, UIComponent component)
 354  
             throws IOException
 355  
     {
 356  
         
 357  0
     }
 358  
 
 359  
     /**
 360  
      * Called after the state and any elements are added to the form tag in the
 361  
      * encodeEnd method
 362  
      */
 363  
     protected void afterFormElementsEnd(FacesContext facesContext, UIComponent component)
 364  
             throws IOException
 365  
     {
 366  
         
 367  0
     }
 368  
 }