Coverage Report - org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
HtmlRendererUtils
7%
61/783
9%
48/528
3.658
HtmlRendererUtils$LinkParameter
0%
0/7
N/A
3.658
HtmlRendererUtils$ScriptContext
33%
2/6
N/A
3.658
 
 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.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.Collection;
 25  
 import java.util.Collections;
 26  
 import java.util.HashMap;
 27  
 import java.util.Iterator;
 28  
 import java.util.List;
 29  
 import java.util.Map;
 30  
 import java.util.RandomAccess;
 31  
 import java.util.Set;
 32  
 import java.util.StringTokenizer;
 33  
 import java.util.logging.Level;
 34  
 import java.util.logging.Logger;
 35  
 
 36  
 import javax.faces.FacesException;
 37  
 import javax.faces.component.EditableValueHolder;
 38  
 import javax.faces.component.UIComponent;
 39  
 import javax.faces.component.UIInput;
 40  
 import javax.faces.component.UIOutcomeTarget;
 41  
 import javax.faces.component.UIOutput;
 42  
 import javax.faces.component.UIParameter;
 43  
 import javax.faces.component.UISelectBoolean;
 44  
 import javax.faces.component.UISelectMany;
 45  
 import javax.faces.component.UISelectOne;
 46  
 import javax.faces.component.UIViewRoot;
 47  
 import javax.faces.component.behavior.ClientBehavior;
 48  
 import javax.faces.component.behavior.ClientBehaviorContext;
 49  
 import javax.faces.component.behavior.ClientBehaviorHint;
 50  
 import javax.faces.component.behavior.ClientBehaviorHolder;
 51  
 import javax.faces.component.html.HtmlDataTable;
 52  
 import javax.faces.component.html.HtmlMessages;
 53  
 import javax.faces.component.html.HtmlPanelGrid;
 54  
 import javax.faces.context.ExternalContext;
 55  
 import javax.faces.context.FacesContext;
 56  
 import javax.faces.context.ResponseWriter;
 57  
 import javax.faces.convert.Converter;
 58  
 import javax.faces.model.SelectItem;
 59  
 import javax.faces.model.SelectItemGroup;
 60  
 
 61  
 import org.apache.myfaces.shared.component.DisplayValueOnlyCapable;
 62  
 import org.apache.myfaces.shared.component.EscapeCapable;
 63  
 import org.apache.myfaces.shared.renderkit.ClientBehaviorEvents;
 64  
 import org.apache.myfaces.shared.renderkit.JSFAttr;
 65  
 import org.apache.myfaces.shared.renderkit.RendererUtils;
 66  
 import org.apache.myfaces.shared.renderkit.html.util.FormInfo;
 67  
 import org.apache.myfaces.shared.renderkit.html.util.HTMLEncoder;
 68  
 import org.apache.myfaces.shared.renderkit.html.util.OutcomeTargetUtils;
 69  
 import org.apache.myfaces.shared.util.StringUtils;
 70  
 
 71  
 public final class HtmlRendererUtils
 72  
 {
 73  
     //private static final Log log = LogFactory.getLog(HtmlRendererUtils.class);
 74  1
     private static final Logger log = Logger.getLogger(HtmlRendererUtils.class
 75  
             .getName());
 76  
     //private static final String[] EMPTY_STRING_ARRAY = new String[0];
 77  1
     private static final String LINE_SEPARATOR = System.getProperty(
 78  
             "line.separator", "\r\n");
 79  
     private static final char TABULATOR = '\t';
 80  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME = "_idcl";
 81  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME_MYFACES_OLD = "_link_hidden_";
 82  
     public static final String HIDDEN_COMMANDLINK_FIELD_NAME_TRINIDAD = "source";
 83  
     public static final String CLEAR_HIDDEN_FIELD_FN_NAME = "clearFormHiddenParams";
 84  
     public static final String SUBMIT_FORM_FN_NAME = "oamSubmitForm";
 85  
     public static final String SUBMIT_FORM_FN_NAME_JSF2 = "myfaces.oam.submitForm";
 86  
     public static final String ALLOW_CDATA_SECTION_ON = "org.apache.myfaces.ResponseWriter.CdataSectionOn";
 87  
     public static final String NON_SUBMITTED_VALUE_WARNING 
 88  
             = "There should always be a submitted value for an input if it is rendered,"
 89  
             + " its form is submitted, and it was not originally rendered disabled or read-only."
 90  
             + "  You cannot submit a form after disabling an input element via javascript."
 91  
             + "  Consider setting read-only to true instead"
 92  
             + " or resetting the disabled value back to false prior to form submission.";
 93  
     public static final String STR_EMPTY = "";
 94  
 
 95  
     private HtmlRendererUtils()
 96  0
     {
 97  
         // utility class, do not instantiate
 98  0
     }
 99  
 
 100  
     /**
 101  
      * Utility to set the submitted value of the provided component from the
 102  
      * data in the current request object.
 103  
      * <p/>
 104  
      * Param component is required to be an EditableValueHolder. On return
 105  
      * from this method, the component's submittedValue property will be
 106  
      * set if the submitted form contained that component.
 107  
      */
 108  
     public static void decodeUIInput(FacesContext facesContext, UIComponent component)
 109  
     {
 110  0
         if (!(component instanceof EditableValueHolder))
 111  
         {
 112  0
             throw new IllegalArgumentException("Component "
 113  
                     + component.getClientId(facesContext)
 114  
                     + " is not an EditableValueHolder");
 115  
         }
 116  0
         Map paramMap = facesContext.getExternalContext()
 117  
                 .getRequestParameterMap();
 118  0
         String clientId = component.getClientId(facesContext);
 119  0
         if (isDisabledOrReadOnly(component))
 120  
         {
 121  0
             return;
 122  
         }
 123  0
         if (paramMap.containsKey(clientId))
 124  
         {
 125  0
             ((EditableValueHolder) component).setSubmittedValue(paramMap
 126  
                     .get(clientId));
 127  
         }
 128  
         else
 129  
         {
 130  0
             log.warning(NON_SUBMITTED_VALUE_WARNING + " Component : "
 131  
                     + RendererUtils.getPathToComponent(component));
 132  
         }
 133  0
     }
 134  
 
 135  
     /**
 136  
      * X-CHECKED: tlddoc h:selectBooleanCheckbox
 137  
      *
 138  
      * @param facesContext
 139  
      * @param component
 140  
      */
 141  
     public static void decodeUISelectBoolean(FacesContext facesContext, UIComponent component)
 142  
     {
 143  0
         if (!(component instanceof EditableValueHolder))
 144  
         {
 145  0
             throw new IllegalArgumentException("Component "
 146  
                     + component.getClientId(facesContext)
 147  
                     + " is not an EditableValueHolder");
 148  
         }
 149  0
         if (isDisabledOrReadOnly(component))
 150  
         {
 151  0
             return;
 152  
         }
 153  0
         Map paramMap = facesContext.getExternalContext()
 154  
                 .getRequestParameterMap();
 155  0
         String clientId = component.getClientId(facesContext);
 156  0
         if (paramMap.containsKey(clientId))
 157  
         {
 158  0
             String reqValue = (String) paramMap.get(clientId);
 159  0
             if ((reqValue.equalsIgnoreCase("on")
 160  
                     || reqValue.equalsIgnoreCase("yes") || reqValue
 161  
                     .equalsIgnoreCase("true")))
 162  
             {
 163  0
                 ((EditableValueHolder) component).setSubmittedValue(Boolean.TRUE);
 164  
             }
 165  
             else
 166  
             {
 167  0
                 ((EditableValueHolder) component).setSubmittedValue(Boolean.FALSE);
 168  
             }
 169  0
         }
 170  
         else
 171  
         {
 172  0
             ((EditableValueHolder) component).setSubmittedValue(Boolean.FALSE);
 173  
         }
 174  0
     }
 175  
 
 176  
     public static boolean isDisabledOrReadOnly(UIComponent component)
 177  
     {
 178  0
         return isDisplayValueOnly(component) || isDisabled(component) || isReadOnly(component);
 179  
     }
 180  
 
 181  
     public static boolean isDisabled(UIComponent component)
 182  
     {
 183  0
         return isTrue(component.getAttributes().get("disabled"));
 184  
     }
 185  
 
 186  
     public static boolean isReadOnly(UIComponent component)
 187  
     {
 188  0
         return isTrue(component.getAttributes().get("readonly"));
 189  
     }
 190  
 
 191  
     private static boolean isTrue(Object obj)
 192  
     {
 193  0
         if (obj instanceof String)
 194  
         {
 195  0
             return Boolean.valueOf((String) obj);
 196  
         }
 197  0
         if (!(obj instanceof Boolean))
 198  
         {
 199  0
             return false;
 200  
         }
 201  0
         return ((Boolean) obj).booleanValue();
 202  
     }
 203  
 
 204  
     /**
 205  
      * X-CHECKED: tlddoc h:selectManyListbox
 206  
      *
 207  
      * @param facesContext
 208  
      * @param component
 209  
      */
 210  
     public static void decodeUISelectMany(FacesContext facesContext, UIComponent component)
 211  
     {
 212  0
         if (!(component instanceof EditableValueHolder))
 213  
         {
 214  0
             throw new IllegalArgumentException("Component "
 215  
                     + component.getClientId(facesContext)
 216  
                     + " is not an EditableValueHolder");
 217  
         }
 218  0
         Map paramValuesMap = facesContext.getExternalContext().getRequestParameterValuesMap();
 219  0
         String clientId = component.getClientId(facesContext);
 220  0
         if (isDisabledOrReadOnly(component))
 221  
         {
 222  0
             return;
 223  
         }
 224  0
         if (paramValuesMap.containsKey(clientId))
 225  
         {
 226  0
             String[] reqValues = (String[]) paramValuesMap.get(clientId);
 227  0
             ((EditableValueHolder) component).setSubmittedValue(reqValues);
 228  0
         }
 229  
         else
 230  
         {
 231  
             /* request parameter not found, nothing to decode - set submitted value to an empty array
 232  
                as we should get here only if the component is on a submitted form, is rendered
 233  
                and if the component is not readonly or has not been disabled.
 234  
                So in fact, there must be component value at this location, but for listboxes, comboboxes etc.
 235  
                the submitted value is not posted if no item is selected. */
 236  0
             ((EditableValueHolder) component).setSubmittedValue(new String[] {});
 237  
         }
 238  0
     }
 239  
 
 240  
     /**
 241  
      * X-CHECKED: tlddoc h:selectManyListbox
 242  
      *
 243  
      * @param facesContext
 244  
      * @param component
 245  
      */
 246  
     public static void decodeUISelectOne(FacesContext facesContext, UIComponent component)
 247  
     {
 248  0
         if (!(component instanceof EditableValueHolder))
 249  
         {
 250  0
             throw new IllegalArgumentException("Component "
 251  
                     + component.getClientId(facesContext)
 252  
                     + " is not an EditableValueHolder");
 253  
         }
 254  0
         if (isDisabledOrReadOnly(component))
 255  
         {
 256  0
             return;
 257  
         }
 258  0
         Map paramMap = facesContext.getExternalContext().getRequestParameterMap();
 259  0
         String clientId = component.getClientId(facesContext);
 260  0
         if (paramMap.containsKey(clientId))
 261  
         {
 262  
             //request parameter found, set submitted value
 263  0
             ((EditableValueHolder) component).setSubmittedValue(paramMap.get(clientId));
 264  
         }
 265  
         else
 266  
         {
 267  
             //see reason for this action at decodeUISelectMany
 268  0
             ((EditableValueHolder) component).setSubmittedValue(STR_EMPTY);
 269  
         }
 270  0
     }
 271  
 
 272  
     /**
 273  
      * @since 4.0.0
 274  
      */
 275  
     public static void decodeClientBehaviors(FacesContext facesContext, UIComponent component)
 276  
     {
 277  0
         if (component instanceof ClientBehaviorHolder)
 278  
         {
 279  0
             ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) component;
 280  0
             Map<String, List<ClientBehavior>> clientBehaviors = clientBehaviorHolder
 281  
                     .getClientBehaviors();
 282  0
             if (clientBehaviors != null && !clientBehaviors.isEmpty())
 283  
             {
 284  0
                 Map<String, String> paramMap = facesContext
 285  
                         .getExternalContext().getRequestParameterMap();
 286  0
                 String behaviorEventName = paramMap
 287  
                         .get("javax.faces.behavior.event");
 288  0
                 if (behaviorEventName != null)
 289  
                 {
 290  0
                     List<ClientBehavior> clientBehaviorList = clientBehaviors
 291  
                             .get(behaviorEventName);
 292  0
                     if (clientBehaviorList != null
 293  
                             && !clientBehaviorList.isEmpty())
 294  
                     {
 295  0
                         String sourceId = paramMap.get("javax.faces.source");
 296  0
                         String componentClientId = component.getClientId(facesContext);
 297  0
                         String clientId = sourceId;
 298  0
                         if (sourceId.startsWith(componentClientId) &&
 299  
                             sourceId.length() > componentClientId.length())
 300  
                         {
 301  0
                             String item = sourceId.substring(componentClientId.length()+1);
 302  
                             // If is item it should be an integer number, otherwise it can be related to a child 
 303  
                             // component, because that could conflict with the clientId naming convention.
 304  0
                             if (StringUtils.isInteger(item))
 305  
                             {
 306  0
                                 clientId = componentClientId;
 307  
                             }
 308  
                         }
 309  0
                         if (component.getClientId(facesContext).equals(clientId))
 310  
                         {
 311  0
                             if (clientBehaviorList instanceof RandomAccess)
 312  
                             {
 313  0
                                 for (int i = 0, size = clientBehaviorList.size(); i < size; i++)
 314  
                                 {
 315  0
                                     ClientBehavior clientBehavior = clientBehaviorList.get(i);
 316  0
                                     clientBehavior.decode(facesContext, component);
 317  
                                 }
 318  
                             } 
 319  
                             else
 320  
                             {
 321  0
                                 for (ClientBehavior clientBehavior : clientBehaviorList)
 322  
                                 {
 323  0
                                     clientBehavior.decode(facesContext, component);
 324  0
                                 }
 325  
                             }
 326  
                         }
 327  
                     }
 328  
                 }
 329  
             }
 330  
         }
 331  0
     }
 332  
 
 333  
     public static void renderListbox(FacesContext facesContext,
 334  
             UISelectOne selectOne, boolean disabled, int size,
 335  
             Converter converter) throws IOException
 336  
     {
 337  0
         internalRenderSelect(facesContext, selectOne, disabled, size, false, converter);
 338  0
     }
 339  
 
 340  
     public static void renderListbox(FacesContext facesContext,
 341  
             UISelectMany selectMany, boolean disabled, int size,
 342  
             Converter converter) throws IOException
 343  
     {
 344  0
         internalRenderSelect(facesContext, selectMany, disabled, size, true, converter);
 345  0
     }
 346  
 
 347  
     public static void renderMenu(FacesContext facesContext,
 348  
             UISelectOne selectOne, boolean disabled, Converter converter)
 349  
             throws IOException
 350  
     {
 351  0
         internalRenderSelect(facesContext, selectOne, disabled, 1, false, converter);
 352  0
     }
 353  
 
 354  
     public static void renderMenu(FacesContext facesContext,
 355  
             UISelectMany selectMany, boolean disabled, Converter converter)
 356  
             throws IOException
 357  
     {
 358  0
         internalRenderSelect(facesContext, selectMany, disabled, 1, true, converter);
 359  0
     }
 360  
 
 361  
     private static void internalRenderSelect(FacesContext facesContext,
 362  
             UIComponent uiComponent, boolean disabled, int size,
 363  
             boolean selectMany, Converter converter) throws IOException
 364  
     {
 365  0
         ResponseWriter writer = facesContext.getResponseWriter();
 366  0
         writer.startElement(HTML.SELECT_ELEM, uiComponent);
 367  0
         if (uiComponent instanceof ClientBehaviorHolder
 368  
                 && !((ClientBehaviorHolder) uiComponent).getClientBehaviors().isEmpty())
 369  
         {
 370  0
             writer.writeAttribute(HTML.ID_ATTR, uiComponent.getClientId(facesContext), null);
 371  
         }
 372  
         else
 373  
         {
 374  0
             HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
 375  
         }
 376  0
         writer.writeAttribute(HTML.NAME_ATTR,
 377  
                 uiComponent.getClientId(facesContext), null);
 378  
         List selectItemList;
 379  0
         if (selectMany)
 380  
         {
 381  0
             writer.writeAttribute(HTML.MULTIPLE_ATTR, HTML.MULTIPLE_ATTR, null);
 382  0
             selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils
 383  
                     .getSelectItemList((UISelectMany) uiComponent, facesContext);
 384  
         }
 385  
         else
 386  
         {
 387  0
             selectItemList = RendererUtils.getSelectItemList(
 388  
                     (UISelectOne) uiComponent, facesContext);
 389  
         }
 390  
 
 391  0
         if (size == Integer.MIN_VALUE)
 392  
         {
 393  
             //No size given (Listbox) --> size is number of select items
 394  0
             writer.writeAttribute(HTML.SIZE_ATTR,
 395  
                     Integer.toString(selectItemList.size()), null);
 396  
         }
 397  
         else
 398  
         {
 399  0
             writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
 400  
         }
 401  0
         Map<String, List<ClientBehavior>> behaviors = null;
 402  0
         if (uiComponent instanceof ClientBehaviorHolder)
 403  
         {
 404  0
             behaviors = ((ClientBehaviorHolder) uiComponent)
 405  
                     .getClientBehaviors();
 406  0
             renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
 407  0
             renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
 408  0
             renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext, writer, uiComponent, behaviors);
 409  0
             renderHTMLAttributes(
 410  
                     writer,
 411  
                     uiComponent,
 412  
                     HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
 413  
         }
 414  
         else
 415  
         {
 416  0
             renderHTMLAttributes(writer, uiComponent,
 417  
                     HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
 418  
         }
 419  
 
 420  0
         if (disabled)
 421  
         {
 422  0
             writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
 423  
         }
 424  
 
 425  0
         if (isReadOnly(uiComponent))
 426  
         {
 427  0
             writer.writeAttribute(HTML.READONLY_ATTR, HTML.READONLY_ATTR, null);
 428  
         }
 429  
 
 430  0
         Set lookupSet = getSubmittedOrSelectedValuesAsSet(selectMany,
 431  
                 uiComponent, facesContext, converter);
 432  
 
 433  0
         renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
 434  
                 selectItemList);
 435  
         // bug #970747: force separate end tag
 436  0
         writer.writeText(STR_EMPTY, null);
 437  0
         writer.endElement(HTML.SELECT_ELEM);
 438  0
     }
 439  
 
 440  
     public static Set getSubmittedOrSelectedValuesAsSet(boolean selectMany,
 441  
             UIComponent uiComponent, FacesContext facesContext, Converter converter)
 442  
     {
 443  
         Set lookupSet;
 444  0
         if (selectMany)
 445  
         {
 446  0
             UISelectMany uiSelectMany = (UISelectMany) uiComponent;
 447  0
             lookupSet = RendererUtils.getSubmittedValuesAsSet(facesContext,
 448  
                     uiComponent, converter, uiSelectMany);
 449  0
             if (lookupSet == null)
 450  
             {
 451  0
                 lookupSet = RendererUtils.getSelectedValuesAsSet(facesContext,
 452  
                         uiComponent, converter, uiSelectMany);
 453  
             }
 454  0
         }
 455  
         else
 456  
         {
 457  0
             UISelectOne uiSelectOne = (UISelectOne) uiComponent;
 458  0
             Object lookup = uiSelectOne.getSubmittedValue();
 459  0
             if (lookup == null)
 460  
             {
 461  0
                 lookup = uiSelectOne.getValue();
 462  0
                 String lookupString = RendererUtils.getConvertedStringValue(
 463  
                         facesContext, uiComponent, converter, lookup);
 464  0
                 lookupSet = Collections.singleton(lookupString);
 465  0
             }
 466  0
             else if (STR_EMPTY.equals(lookup))
 467  
             {
 468  0
                 lookupSet = Collections.EMPTY_SET;
 469  
             }
 470  
             else
 471  
             {
 472  0
                 lookupSet = Collections.singleton(lookup);
 473  
             }
 474  
         }
 475  0
         return lookupSet;
 476  
     }
 477  
 
 478  
     public static Converter findUISelectManyConverterFailsafe(
 479  
             FacesContext facesContext, UIComponent uiComponent)
 480  
     {
 481  
         // invoke with considerValueType = false
 482  0
         return findUISelectManyConverterFailsafe(facesContext, uiComponent, false);
 483  
     }
 484  
 
 485  
     public static Converter findUISelectManyConverterFailsafe(
 486  
             FacesContext facesContext, UIComponent uiComponent,
 487  
             boolean considerValueType)
 488  
     {
 489  
         Converter converter;
 490  
         try
 491  
         {
 492  0
             converter = RendererUtils.findUISelectManyConverter(facesContext,
 493  
                     (UISelectMany) uiComponent, considerValueType);
 494  
         }
 495  0
         catch (FacesException e)
 496  
         {
 497  0
             log.log(Level.SEVERE,
 498  
                     "Error finding Converter for component with id "
 499  
                             + uiComponent.getClientId(facesContext), e);
 500  0
             converter = null;
 501  0
         }
 502  0
         return converter;
 503  
     }
 504  
 
 505  
     public static Converter findUIOutputConverterFailSafe(FacesContext facesContext, UIComponent uiComponent)
 506  
     {
 507  
         Converter converter;
 508  
         try
 509  
         {
 510  0
             converter = RendererUtils.findUIOutputConverter(facesContext, (UIOutput) uiComponent);
 511  
         }
 512  0
         catch (FacesException e)
 513  
         {
 514  0
             log.log(Level.SEVERE,
 515  
                     "Error finding Converter for component with id "
 516  
                             + uiComponent.getClientId(facesContext), e);
 517  0
             converter = null;
 518  0
         }
 519  0
         return converter;
 520  
     }
 521  
 
 522  
     /**
 523  
      * Renders the select options for a <code>UIComponent</code> that is
 524  
      * rendered as an HTML select element.
 525  
      *
 526  
      * @param context        the current <code>FacesContext</code>.
 527  
      * @param component      the <code>UIComponent</code> whose options need to be
 528  
      *                       rendered.
 529  
      * @param converter      <code>component</code>'s converter
 530  
      * @param lookupSet      the <code>Set</code> to use to look up selected options
 531  
      * @param selectItemList the <code>List</code> of <code>SelectItem</code> s to be
 532  
      *                       rendered as HTML option elements.
 533  
      * @throws IOException
 534  
      */
 535  
     public static void renderSelectOptions(FacesContext context,
 536  
             UIComponent component, Converter converter, Set lookupSet,
 537  
             List selectItemList) throws IOException
 538  
     {
 539  0
         ResponseWriter writer = context.getResponseWriter();
 540  
         // check for the hideNoSelectionOption attribute
 541  0
         boolean hideNoSelectionOption = isHideNoSelectionOption(component);
 542  0
         boolean componentDisabled = isTrue(component.getAttributes()
 543  
                 .get("disabled"));
 544  
 
 545  0
         for (Iterator it = selectItemList.iterator(); it.hasNext();)
 546  
         {
 547  0
             SelectItem selectItem = (SelectItem) it.next();
 548  0
             if (selectItem instanceof SelectItemGroup)
 549  
             {
 550  0
                 writer.startElement(HTML.OPTGROUP_ELEM, null); // component);
 551  0
                 writer.writeAttribute(HTML.LABEL_ATTR, selectItem.getLabel(),
 552  
                         null);
 553  0
                 SelectItem[] selectItems = ((SelectItemGroup) selectItem)
 554  
                         .getSelectItems();
 555  0
                 renderSelectOptions(context, component, converter, lookupSet,
 556  
                         Arrays.asList(selectItems));
 557  0
                 writer.endElement(HTML.OPTGROUP_ELEM);
 558  0
             }
 559  
             else
 560  
             {
 561  0
                 String itemStrValue = org.apache.myfaces.shared.renderkit.RendererUtils
 562  
                         .getConvertedStringValue(context, component, converter,
 563  
                                 selectItem);
 564  0
                 boolean selected = lookupSet.contains(itemStrValue); 
 565  
                 //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings 
 566  
                 //only when useSubmittedValue==true, else use the real item value Objects
 567  
 
 568  
                 // IF the hideNoSelectionOption attribute of the component is true
 569  
                 // AND this selectItem is the "no selection option"
 570  
                 // AND there are currently selected items 
 571  
                 // AND this item (the "no selection option") is not selected
 572  
                 // (if there is currently no value on UISelectOne, lookupSet contains "")
 573  0
                 if (hideNoSelectionOption && selectItem.isNoSelectionOption()
 574  
                         && lookupSet.size() != 0
 575  
                         && !(lookupSet.size() == 1 && lookupSet.contains(""))
 576  
                         && !selected)
 577  
                 {
 578  
                     // do not render this selectItem
 579  0
                     continue;
 580  
                 }
 581  
 
 582  0
                 writer.write(TABULATOR);
 583  0
                 writer.startElement(HTML.OPTION_ELEM, null); // component);
 584  0
                 if (itemStrValue != null)
 585  
                 {
 586  0
                     writer.writeAttribute(HTML.VALUE_ATTR, itemStrValue, null);
 587  
                 }
 588  
                 else
 589  
                 {
 590  0
                     writer.writeAttribute(HTML.VALUE_ATTR, "", null);
 591  
                 }
 592  
 
 593  0
                 if (selected)
 594  
                 {
 595  0
                     writer.writeAttribute(HTML.SELECTED_ATTR, HTML.SELECTED_ATTR, null);
 596  
                 }
 597  
 
 598  0
                 boolean disabled = selectItem.isDisabled();
 599  0
                 if (disabled)
 600  
                 {
 601  0
                     writer.writeAttribute(HTML.DISABLED_ATTR, HTML.DISABLED_ATTR, null);
 602  
                 }
 603  
 
 604  0
                 String labelClass = null;
 605  
 
 606  0
                 if (componentDisabled || disabled)
 607  
                 {
 608  0
                     labelClass = (String) component.getAttributes().get(
 609  
                             JSFAttr.DISABLED_CLASS_ATTR);
 610  
                 }
 611  
                 else
 612  
                 {
 613  0
                     labelClass = (String) component.getAttributes().get(
 614  
                             JSFAttr.ENABLED_CLASS_ATTR);
 615  
                 }
 616  0
                 if (labelClass != null)
 617  
                 {
 618  0
                     writer.writeAttribute("class", labelClass, "labelClass");
 619  
                 }
 620  
 
 621  
                 boolean escape;
 622  0
                 if (component instanceof EscapeCapable)
 623  
                 {
 624  0
                     escape = ((EscapeCapable) component).isEscape();
 625  
 
 626  
                     // Preserve tomahawk semantic. If escape=false
 627  
                     // all items should be non escaped. If escape
 628  
                     // is true check if selectItem.isEscape() is
 629  
                     // true and do it.
 630  
                     // This is done for remain compatibility.
 631  0
                     if (escape && selectItem.isEscape())
 632  
                     {
 633  0
                         writer.writeText(selectItem.getLabel(), null);
 634  
                     }
 635  
                     else
 636  
                     {
 637  0
                         writer.write(selectItem.getLabel());
 638  
                     }
 639  
                 }
 640  
                 else
 641  
                 {
 642  0
                     escape = RendererUtils.getBooleanAttribute(component,
 643  
                             JSFAttr.ESCAPE_ATTR, false);
 644  
                     //default is to escape
 645  
                     //In JSF 1.2, when a SelectItem is created by default 
 646  
                     //selectItem.isEscape() returns true (this property
 647  
                     //is not available on JSF 1.1).
 648  
                     //so, if we found a escape property on the component
 649  
                     //set to true, escape every item, but if not
 650  
                     //check if isEscape() = true first.
 651  0
                     if (escape || selectItem.isEscape())
 652  
                     {
 653  0
                         writer.writeText(selectItem.getLabel(), null);
 654  
                     }
 655  
                     else
 656  
                     {
 657  0
                         writer.write(selectItem.getLabel());
 658  
                     }
 659  
                 }
 660  
 
 661  0
                 writer.endElement(HTML.OPTION_ELEM);
 662  
             }
 663  0
         }
 664  0
     }
 665  
 
 666  
     /**
 667  
      * @return true, if the attribute was written
 668  
      * @throws java.io.IOException
 669  
      */
 670  
     public static boolean renderHTMLAttribute(ResponseWriter writer,
 671  
             String componentProperty, String attrName, Object value)
 672  
             throws IOException
 673  
     {
 674  0
         if (!RendererUtils.isDefaultAttributeValue(value))
 675  
         {
 676  
             // render JSF "styleClass" and "itemStyleClass" attributes as "class"
 677  0
             String htmlAttrName = attrName.equals(HTML.STYLE_CLASS_ATTR) ? HTML.CLASS_ATTR
 678  
                     : attrName;
 679  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 680  0
             return true;
 681  
         }
 682  
 
 683  0
         return false;
 684  
     }
 685  
 
 686  
     /**
 687  
      * @return true, if the attribute was written
 688  
      * @throws java.io.IOException
 689  
      */
 690  
     public static boolean renderHTMLAttribute(ResponseWriter writer,
 691  
             UIComponent component, String componentProperty, String htmlAttrName)
 692  
             throws IOException
 693  
     {
 694  0
         Object value = component.getAttributes().get(componentProperty);
 695  0
         return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
 696  
                 value);
 697  
     }
 698  
 
 699  
     /**
 700  
      * @return true, if an attribute was written
 701  
      * @throws java.io.IOException
 702  
      */
 703  
     public static boolean renderHTMLAttributes(ResponseWriter writer,
 704  
             UIComponent component, String[] attributes) throws IOException
 705  
     {
 706  0
         boolean somethingDone = false;
 707  0
         for (int i = 0, len = attributes.length; i < len; i++)
 708  
         {
 709  0
             String attrName = attributes[i];
 710  0
             if (renderHTMLAttribute(writer, component, attrName, attrName))
 711  
             {
 712  0
                 somethingDone = true;
 713  
             }
 714  
         }
 715  0
         return somethingDone;
 716  
     }
 717  
 
 718  
     public static boolean renderHTMLAttributeWithOptionalStartElement(
 719  
             ResponseWriter writer, UIComponent component, String elementName,
 720  
             String attrName, Object value, boolean startElementWritten)
 721  
             throws IOException
 722  
     {
 723  0
         if (!org.apache.myfaces.shared.renderkit.RendererUtils
 724  
                 .isDefaultAttributeValue(value))
 725  
         {
 726  0
             if (!startElementWritten)
 727  
             {
 728  0
                 writer.startElement(elementName, component);
 729  0
                 startElementWritten = true;
 730  
             }
 731  0
             renderHTMLAttribute(writer, attrName, attrName, value);
 732  
         }
 733  0
         return startElementWritten;
 734  
     }
 735  
 
 736  
     public static boolean renderHTMLAttributesWithOptionalStartElement(
 737  
             ResponseWriter writer, UIComponent component, String elementName,
 738  
             String[] attributes) throws IOException
 739  
     {
 740  0
         boolean startElementWritten = false;
 741  0
         for (int i = 0, len = attributes.length; i < len; i++)
 742  
         {
 743  0
             String attrName = attributes[i];
 744  0
             Object value = component.getAttributes().get(attrName);
 745  0
             if (!RendererUtils.isDefaultAttributeValue(value))
 746  
             {
 747  0
                 if (!startElementWritten)
 748  
                 {
 749  0
                     writer.startElement(elementName, component);
 750  0
                     startElementWritten = true;
 751  
                 }
 752  0
                 renderHTMLAttribute(writer, attrName, attrName, value);
 753  
             }
 754  
         }
 755  0
         return startElementWritten;
 756  
     }
 757  
 
 758  
     public static boolean renderOptionalEndElement(ResponseWriter writer,
 759  
             UIComponent component, String elementName, String[] attributes)
 760  
             throws IOException
 761  
     {
 762  0
         boolean endElementNeeded = false;
 763  0
         for (int i = 0, len = attributes.length; i < len; i++)
 764  
         {
 765  0
             String attrName = attributes[i];
 766  0
             Object value = component.getAttributes().get(attrName);
 767  0
             if (!RendererUtils.isDefaultAttributeValue(value))
 768  
             {
 769  0
                 endElementNeeded = true;
 770  0
                 break;
 771  
             }
 772  
         }
 773  0
         if (endElementNeeded)
 774  
         {
 775  0
             writer.endElement(elementName);
 776  0
             return true;
 777  
         }
 778  
 
 779  0
         return false;
 780  
     }
 781  
 
 782  
     public static void writeIdIfNecessary(ResponseWriter writer,
 783  
             UIComponent component, FacesContext facesContext)
 784  
             throws IOException
 785  
     {
 786  0
         if (component.getId() != null
 787  
                 && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
 788  
         {
 789  0
             writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext), null);
 790  
         }
 791  0
     }
 792  
 
 793  
     public static void writeIdAndNameIfNecessary(ResponseWriter writer,
 794  
             UIComponent component, FacesContext facesContext)
 795  
             throws IOException
 796  
     {
 797  0
         if (component.getId() != null
 798  
                 && !component.getId().startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
 799  
         {
 800  0
             String clientId = component.getClientId(facesContext);
 801  0
             writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 802  0
             writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 803  
         }
 804  0
     }
 805  
     
 806  
     /**
 807  
      * Renders a html string type attribute. If the value retrieved from the component 
 808  
      * property is "", the attribute is rendered.
 809  
      * 
 810  
      * @param writer
 811  
      * @param component
 812  
      * @param componentProperty
 813  
      * @param htmlAttrName
 814  
      * @return
 815  
      * @throws IOException
 816  
      */
 817  
     public static final boolean renderHTMLStringPreserveEmptyAttribute(ResponseWriter writer,
 818  
             UIComponent component, String componentProperty, String htmlAttrName)
 819  
             throws IOException
 820  
     {
 821  0
         String value = (String) component.getAttributes().get(componentProperty);
 822  0
         if (!isDefaultStringPreserveEmptyAttributeValue(value))
 823  
         {
 824  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 825  0
             return true;
 826  
         }
 827  0
         return false;
 828  
     }
 829  
     
 830  
     /**
 831  
      * Renders a html string type attribute. If the value retrieved from the component 
 832  
      * property is "", the attribute is rendered.
 833  
      * 
 834  
      * @param writer
 835  
      * @param component
 836  
      * @param componentProperty
 837  
      * @param htmlAttrName
 838  
      * @return
 839  
      * @throws IOException
 840  
      */
 841  
     public static boolean renderHTMLStringPreserveEmptyAttribute(ResponseWriter writer,
 842  
             String componentProperty, String htmlAttrName, String value)
 843  
             throws IOException
 844  
     {
 845  0
         if (!isDefaultStringPreserveEmptyAttributeValue(value))
 846  
         {
 847  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 848  0
             return true;
 849  
         }
 850  0
         return false;
 851  
     }
 852  
 
 853  
     /**
 854  
      * Check if the value is the default for String type attributes that requires preserve "" as
 855  
      * a valid value.
 856  
      * 
 857  
      * @param value
 858  
      * @return
 859  
      */
 860  
     private static boolean isDefaultStringPreserveEmptyAttributeValue(String value)
 861  
     {
 862  0
         if (value == null)
 863  
         {
 864  0
             return true;
 865  
         }
 866  
         else
 867  
         {
 868  0
             return false;
 869  
         }
 870  
     }
 871  
 
 872  
     /**
 873  
      * Renders a html string type attribute. If the value retrieved from the component 
 874  
      * property is "" or null, the attribute is not rendered.
 875  
      * 
 876  
      * @param writer
 877  
      * @param component
 878  
      * @param componentProperty
 879  
      * @param htmlAttrName
 880  
      * @return
 881  
      * @throws IOException
 882  
      */
 883  
     public static boolean renderHTMLStringAttribute(ResponseWriter writer,
 884  
             UIComponent component, String componentProperty, String htmlAttrName)
 885  
             throws IOException
 886  
     {
 887  0
         String value = (String) component.getAttributes().get(componentProperty);
 888  0
         if (!isDefaultStringAttributeValue(value))
 889  
         {
 890  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 891  0
             return true;
 892  
         }
 893  0
         return false;
 894  
     }
 895  
 
 896  
     /**
 897  
      * Renders a html string type attribute. If the value retrieved from the component 
 898  
      * property is "" or null, the attribute is not rendered.
 899  
      * 
 900  
      * @param writer
 901  
      * @param componentProperty
 902  
      * @param htmlAttrName
 903  
      * @param value
 904  
      * @return
 905  
      * @throws IOException
 906  
      */
 907  
     public static boolean renderHTMLStringAttribute(ResponseWriter writer,
 908  
             String componentProperty, String htmlAttrName, String value)
 909  
             throws IOException
 910  
     {
 911  0
         if (!isDefaultStringAttributeValue(value))
 912  
         {
 913  0
             writer.writeAttribute(htmlAttrName, value, componentProperty);
 914  0
             return true;
 915  
         }
 916  0
         return false;
 917  
     }
 918  
     
 919  
     /**
 920  
      * Check if the value is the default for String type attributes (null or "").
 921  
      * 
 922  
      * @param value
 923  
      * @return
 924  
      */
 925  
     private static boolean isDefaultStringAttributeValue(String value)
 926  
     {
 927  0
         if (value == null)
 928  
         {
 929  0
             return true;
 930  
         }
 931  0
         else if (value.length() == 0)
 932  
         {
 933  0
             return true;
 934  
         }
 935  
         else
 936  
         {
 937  0
             return false;
 938  
         }
 939  
     }
 940  
     
 941  
     public static boolean renderHTMLStringNoStyleAttributes(ResponseWriter writer,
 942  
             UIComponent component, String[] attributes) throws IOException
 943  
     {
 944  0
         boolean somethingDone = false;
 945  0
         for (int i = 0, len = attributes.length; i < len; i++)
 946  
         {
 947  0
             String attrName = attributes[i];
 948  0
             if (renderHTMLStringAttribute(writer, component, attrName, attrName))
 949  
             {
 950  0
                 somethingDone = true;
 951  
             }
 952  
         }
 953  0
         return somethingDone;
 954  
     }
 955  
 
 956  
     public static void writeIdAndName(ResponseWriter writer, UIComponent component, FacesContext facesContext)
 957  
             throws IOException
 958  
     {
 959  0
         String clientId = component.getClientId(facesContext);
 960  0
         writer.writeAttribute(HTML.ID_ATTR, clientId, null);
 961  0
         writer.writeAttribute(HTML.NAME_ATTR, clientId, null);
 962  0
     }
 963  
 
 964  
     public static void renderDisplayValueOnlyForSelects(
 965  
             FacesContext facesContext, UIComponent uiComponent)
 966  
             throws IOException
 967  
     {
 968  
         // invoke renderDisplayValueOnlyForSelects with considerValueType = false
 969  0
         renderDisplayValueOnlyForSelects(facesContext, uiComponent, false);
 970  0
     }
 971  
 
 972  
     public static void renderDisplayValueOnlyForSelects(FacesContext facesContext, UIComponent uiComponent,
 973  
             boolean considerValueType) throws IOException
 974  
     {
 975  0
         ResponseWriter writer = facesContext.getResponseWriter();
 976  
 
 977  0
         List selectItemList = null;
 978  0
         Converter converter = null;
 979  0
         boolean isSelectOne = false;
 980  
 
 981  0
         if (uiComponent instanceof UISelectBoolean)
 982  
         {
 983  0
             converter = findUIOutputConverterFailSafe(facesContext, uiComponent);
 984  
 
 985  0
             writer.startElement(HTML.SPAN_ELEM, uiComponent);
 986  0
             writeIdIfNecessary(writer, uiComponent, facesContext);
 987  0
             renderDisplayValueOnlyAttributes(uiComponent, writer);
 988  0
             writer.writeText(RendererUtils.getConvertedStringValue(
 989  
                     facesContext, uiComponent, converter,
 990  
                     ((UISelectBoolean) uiComponent).getValue()),
 991  
                     JSFAttr.VALUE_ATTR);
 992  0
             writer.endElement(HTML.SPAN_ELEM);
 993  
 
 994  
         }
 995  
         else
 996  
         {
 997  0
             if (uiComponent instanceof UISelectMany)
 998  
             {
 999  0
                 isSelectOne = false;
 1000  0
                 selectItemList = RendererUtils.getSelectItemList(
 1001  
                         (UISelectMany) uiComponent, facesContext);
 1002  0
                 converter = findUISelectManyConverterFailsafe(facesContext,
 1003  
                         uiComponent, considerValueType);
 1004  
             }
 1005  0
             else if (uiComponent instanceof UISelectOne)
 1006  
             {
 1007  0
                 isSelectOne = true;
 1008  0
                 selectItemList = RendererUtils.getSelectItemList(
 1009  
                         (UISelectOne) uiComponent, facesContext);
 1010  0
                 converter = findUIOutputConverterFailSafe(facesContext,
 1011  
                         uiComponent);
 1012  
             }
 1013  
 
 1014  0
             writer.startElement(isSelectOne ? HTML.SPAN_ELEM : HTML.UL_ELEM, uiComponent);
 1015  0
             writeIdIfNecessary(writer, uiComponent, facesContext);
 1016  
 
 1017  0
             renderDisplayValueOnlyAttributes(uiComponent, writer);
 1018  
 
 1019  0
             Set lookupSet = getSubmittedOrSelectedValuesAsSet(
 1020  
                     uiComponent instanceof UISelectMany, uiComponent,
 1021  
                     facesContext, converter);
 1022  
 
 1023  0
             renderSelectOptionsAsText(facesContext, uiComponent, converter,
 1024  
                     lookupSet, selectItemList, isSelectOne);
 1025  
 
 1026  
             // bug #970747: force separate end tag
 1027  0
             writer.writeText(STR_EMPTY, null);
 1028  0
             writer.endElement(isSelectOne ? HTML.SPAN_ELEM : HTML.UL_ELEM);
 1029  
         }
 1030  
 
 1031  0
     }
 1032  
 
 1033  
     public static void renderDisplayValueOnlyAttributes(
 1034  
             UIComponent uiComponent, ResponseWriter writer) throws IOException
 1035  
     {
 1036  0
         if (!(uiComponent instanceof org.apache.myfaces.shared.component.DisplayValueOnlyCapable))
 1037  
         {
 1038  0
             log.severe("Wrong type of uiComponent. needs DisplayValueOnlyCapable.");
 1039  0
             renderHTMLAttributes(writer, uiComponent, HTML.COMMON_PASSTROUGH_ATTRIBUTES);
 1040  
 
 1041  0
             return;
 1042  
         }
 1043  
 
 1044  0
         if (getDisplayValueOnlyStyle(uiComponent) != null
 1045  
                 || getDisplayValueOnlyStyleClass(uiComponent) != null)
 1046  
         {
 1047  0
             if (getDisplayValueOnlyStyle(uiComponent) != null)
 1048  
             {
 1049  0
                 writer.writeAttribute(HTML.STYLE_ATTR, getDisplayValueOnlyStyle(uiComponent), null);
 1050  
             }
 1051  0
             else if (uiComponent.getAttributes().get("style") != null)
 1052  
             {
 1053  0
                 writer.writeAttribute(HTML.STYLE_ATTR, uiComponent.getAttributes().get("style"), null);
 1054  
             }
 1055  
 
 1056  0
             if (getDisplayValueOnlyStyleClass(uiComponent) != null)
 1057  
             {
 1058  0
                 writer.writeAttribute(HTML.CLASS_ATTR, getDisplayValueOnlyStyleClass(uiComponent), null);
 1059  
             }
 1060  0
             else if (uiComponent.getAttributes().get("styleClass") != null)
 1061  
             {
 1062  0
                 writer.writeAttribute(HTML.CLASS_ATTR, uiComponent.getAttributes().get("styleClass"), null);
 1063  
             }
 1064  
 
 1065  0
             renderHTMLAttributes(writer, uiComponent, HTML.COMMON_PASSTROUGH_ATTRIBUTES_WITHOUT_STYLE);
 1066  
         }
 1067  
         else
 1068  
         {
 1069  0
             renderHTMLAttributes(writer, uiComponent, HTML.COMMON_PASSTROUGH_ATTRIBUTES);
 1070  
         }
 1071  0
     }
 1072  
 
 1073  
     private static void renderSelectOptionsAsText(FacesContext context,
 1074  
             UIComponent component, Converter converter, Set lookupSet,
 1075  
             List selectItemList, boolean isSelectOne) throws IOException
 1076  
     {
 1077  0
         ResponseWriter writer = context.getResponseWriter();
 1078  
 
 1079  0
         for (Iterator it = selectItemList.iterator(); it.hasNext();)
 1080  
         {
 1081  0
             SelectItem selectItem = (SelectItem) it.next();
 1082  
 
 1083  0
             if (selectItem instanceof SelectItemGroup)
 1084  
             {
 1085  0
                 SelectItem[] selectItems = ((SelectItemGroup) selectItem).getSelectItems();
 1086  0
                 renderSelectOptionsAsText(context, component, converter,
 1087  
                         lookupSet, Arrays.asList(selectItems), isSelectOne);
 1088  0
             }
 1089  
             else
 1090  
             {
 1091  0
                 String itemStrValue = RendererUtils.getConvertedStringValue(
 1092  
                         context, component, converter, selectItem);
 1093  
 
 1094  0
                 if (lookupSet.contains(itemStrValue))
 1095  
                 {
 1096  
                     //TODO/FIX: we always compare the String vales, better fill lookupSet with Strings 
 1097  
                     //only when useSubmittedValue==true, else use the real item value Objects
 1098  0
                     if (!isSelectOne)
 1099  
                     {
 1100  0
                         writer.startElement(HTML.LI_ELEM, null); // component);
 1101  
                     }
 1102  0
                     writer.writeText(selectItem.getLabel(), null);
 1103  0
                     if (!isSelectOne)
 1104  
                     {
 1105  0
                         writer.endElement(HTML.LI_ELEM);
 1106  
                     }
 1107  0
                     if (isSelectOne)
 1108  
                     {
 1109  
                         //take care of several choices with the same value; use only the first one
 1110  0
                         return;
 1111  
                     }
 1112  
                 }
 1113  
             }
 1114  0
         }
 1115  0
     }
 1116  
 
 1117  
     public static void renderTableCaption(FacesContext context,
 1118  
             ResponseWriter writer, UIComponent component) throws IOException
 1119  
     {
 1120  0
         UIComponent captionFacet = component.getFacet("caption");
 1121  0
         if (captionFacet == null)
 1122  
         {
 1123  0
             return;
 1124  
         }
 1125  
         String captionClass;
 1126  
         String captionStyle;
 1127  0
         if (component instanceof HtmlPanelGrid)
 1128  
         {
 1129  0
             HtmlPanelGrid panelGrid = (HtmlPanelGrid) component;
 1130  0
             captionClass = panelGrid.getCaptionClass();
 1131  0
             captionStyle = panelGrid.getCaptionStyle();
 1132  0
         }
 1133  0
         else if (component instanceof HtmlDataTable)
 1134  
         {
 1135  0
             HtmlDataTable dataTable = (HtmlDataTable) component;
 1136  0
             captionClass = dataTable.getCaptionClass();
 1137  0
             captionStyle = dataTable.getCaptionStyle();
 1138  0
         }
 1139  
         else
 1140  
         {
 1141  0
             captionClass = (String) component.getAttributes()
 1142  
                     .get(org.apache.myfaces.shared.renderkit.JSFAttr.CAPTION_CLASS_ATTR);
 1143  0
             captionStyle = (String) component.getAttributes()
 1144  
                     .get(org.apache.myfaces.shared.renderkit.JSFAttr.CAPTION_STYLE_ATTR);
 1145  
         }
 1146  0
         writer.startElement(HTML.CAPTION_ELEM, null); // component);
 1147  0
         if (captionClass != null)
 1148  
         {
 1149  0
             writer.writeAttribute(HTML.CLASS_ATTR, captionClass, null);
 1150  
         }
 1151  
 
 1152  0
         if (captionStyle != null)
 1153  
         {
 1154  0
             writer.writeAttribute(HTML.STYLE_ATTR, captionStyle, null);
 1155  
         }
 1156  
         //RendererUtils.renderChild(context, captionFacet);
 1157  0
         captionFacet.encodeAll(context);
 1158  0
         writer.endElement(HTML.CAPTION_ELEM);
 1159  0
     }
 1160  
 
 1161  
     public static String getDisplayValueOnlyStyleClass(UIComponent component)
 1162  
     {
 1163  0
         if (component instanceof org.apache.myfaces.shared.component.DisplayValueOnlyCapable)
 1164  
         {
 1165  0
             if (((org.apache.myfaces.shared.component.DisplayValueOnlyCapable) component)
 1166  
                     .getDisplayValueOnlyStyleClass() != null)
 1167  
             {
 1168  0
                 return ((DisplayValueOnlyCapable) component)
 1169  
                         .getDisplayValueOnlyStyleClass();
 1170  
             }
 1171  0
             UIComponent parent = component;
 1172  0
             while ((parent = parent.getParent()) != null)
 1173  
             {
 1174  0
                 if (parent instanceof org.apache.myfaces.shared.component.DisplayValueOnlyCapable
 1175  
                         && ((org.apache.myfaces.shared.component.DisplayValueOnlyCapable) parent)
 1176  
                                 .getDisplayValueOnlyStyleClass() != null)
 1177  
                 {
 1178  0
                     return ((org.apache.myfaces.shared.component.DisplayValueOnlyCapable) parent)
 1179  
                             .getDisplayValueOnlyStyleClass();
 1180  
                 }
 1181  
             }
 1182  
         }
 1183  0
         return null;
 1184  
     }
 1185  
 
 1186  
     public static String getDisplayValueOnlyStyle(UIComponent component)
 1187  
     {
 1188  0
         if (component instanceof DisplayValueOnlyCapable)
 1189  
         {
 1190  0
             if (((org.apache.myfaces.shared.component.DisplayValueOnlyCapable) component)
 1191  
                     .getDisplayValueOnlyStyle() != null)
 1192  
             {
 1193  0
                 return ((DisplayValueOnlyCapable) component)
 1194  
                         .getDisplayValueOnlyStyle();
 1195  
             }
 1196  0
             UIComponent parent = component;
 1197  0
             while ((parent = parent.getParent()) != null)
 1198  
             {
 1199  0
                 if (parent instanceof org.apache.myfaces.shared.component.DisplayValueOnlyCapable
 1200  
                         && ((DisplayValueOnlyCapable) parent)
 1201  
                                 .getDisplayValueOnlyStyle() != null)
 1202  
                 {
 1203  0
                     return ((DisplayValueOnlyCapable) parent)
 1204  
                             .getDisplayValueOnlyStyle();
 1205  
                 }
 1206  
             }
 1207  
         }
 1208  0
         return null;
 1209  
     }
 1210  
 
 1211  
     public static boolean isDisplayValueOnly(UIComponent component)
 1212  
     {
 1213  0
         if (component instanceof DisplayValueOnlyCapable)
 1214  
         {
 1215  0
             if (((DisplayValueOnlyCapable) component).isSetDisplayValueOnly())
 1216  
             {
 1217  0
                 return ((DisplayValueOnlyCapable) component).isDisplayValueOnly();
 1218  
             }
 1219  0
             UIComponent parent = component;
 1220  0
             while ((parent = parent.getParent()) != null)
 1221  
             {
 1222  0
                 if (parent instanceof DisplayValueOnlyCapable
 1223  
                         && ((DisplayValueOnlyCapable) parent).isSetDisplayValueOnly())
 1224  
                 {
 1225  0
                     return ((org.apache.myfaces.shared.component.DisplayValueOnlyCapable) parent)
 1226  
                             .isDisplayValueOnly();
 1227  
                 }
 1228  
             }
 1229  
         }
 1230  0
         return false;
 1231  
     }
 1232  
 
 1233  
     public static void renderDisplayValueOnly(FacesContext facesContext,
 1234  
             UIInput input) throws IOException
 1235  
     {
 1236  0
         ResponseWriter writer = facesContext.getResponseWriter();
 1237  0
         writer.startElement(org.apache.myfaces.shared.renderkit.html.HTML.SPAN_ELEM, input);
 1238  0
         writeIdIfNecessary(writer, input, facesContext);
 1239  0
         renderDisplayValueOnlyAttributes(input, writer);
 1240  0
         String strValue = RendererUtils.getStringValue(facesContext, input);
 1241  0
         writer.write(HTMLEncoder.encode(strValue, true, true));
 1242  0
         writer.endElement(HTML.SPAN_ELEM);
 1243  0
     }
 1244  
 
 1245  
     public static void appendClearHiddenCommandFormParamsFunctionCall(
 1246  
             StringBuilder buf, String formName)
 1247  
     {
 1248  0
         HtmlJavaScriptUtils.appendClearHiddenCommandFormParamsFunctionCall(buf, formName);
 1249  0
     }
 1250  
 
 1251  
     @SuppressWarnings("unchecked")
 1252  
     public static void renderFormSubmitScript(FacesContext facesContext)
 1253  
             throws IOException
 1254  
     {
 1255  0
         HtmlJavaScriptUtils.renderFormSubmitScript(facesContext);
 1256  0
     }
 1257  
 
 1258  
     /**
 1259  
      * Adds the hidden form input value assignment that is necessary for the autoscroll
 1260  
      * feature to an html link or button onclick attribute.
 1261  
      */
 1262  
     public static void appendAutoScrollAssignment(StringBuilder onClickValue,
 1263  
             String formName)
 1264  
     {
 1265  0
         HtmlJavaScriptUtils.appendAutoScrollAssignment(onClickValue, formName);
 1266  0
     }
 1267  
 
 1268  
     /**
 1269  
      * Adds the hidden form input value assignment that is necessary for the autoscroll
 1270  
      * feature to an html link or button onclick attribute.
 1271  
      */
 1272  
     public static void appendAutoScrollAssignment(FacesContext context,
 1273  
             StringBuilder onClickValue, String formName)
 1274  
     {
 1275  0
         HtmlJavaScriptUtils.appendAutoScrollAssignment(context, onClickValue, formName);
 1276  0
     }
 1277  
 
 1278  
     /**
 1279  
      * Renders the hidden form input that is necessary for the autoscroll feature.
 1280  
      */
 1281  
     public static void renderAutoScrollHiddenInput(FacesContext facesContext,
 1282  
             ResponseWriter writer) throws IOException
 1283  
     {
 1284  0
         HtmlJavaScriptUtils.renderAutoScrollHiddenInput(facesContext, writer);
 1285  0
     }
 1286  
 
 1287  
     /**
 1288  
      * Renders the autoscroll javascript function.
 1289  
      */
 1290  
     public static void renderAutoScrollFunction(FacesContext facesContext,
 1291  
             ResponseWriter writer) throws IOException
 1292  
     {
 1293  0
         HtmlJavaScriptUtils.renderAutoScrollFunction(facesContext, writer);
 1294  0
     }
 1295  
 
 1296  
     public static String getAutoScrollFunction(FacesContext facesContext)
 1297  
     {
 1298  0
         return HtmlJavaScriptUtils.getAutoScrollFunction(facesContext);
 1299  
     }
 1300  
 
 1301  
     public static boolean isAllowedCdataSection(FacesContext fc)
 1302  
     {
 1303  0
         Boolean value = null;
 1304  0
         if (fc != null)
 1305  
         {
 1306  0
             value = (Boolean) fc.getExternalContext().getRequestMap().get(ALLOW_CDATA_SECTION_ON);
 1307  
         }
 1308  0
         return value != null && ((Boolean) value).booleanValue();
 1309  
     }
 1310  
 
 1311  
     public static void allowCdataSection(FacesContext fc, boolean cdataSectionAllowed)
 1312  
     {
 1313  0
         fc.getExternalContext().getRequestMap().put(ALLOW_CDATA_SECTION_ON, Boolean.valueOf(cdataSectionAllowed));
 1314  0
     }
 1315  
 
 1316  0
     public static class LinkParameter
 1317  
     {
 1318  
         private String _name;
 1319  
 
 1320  
         private Object _value;
 1321  
 
 1322  
         public String getName()
 1323  
         {
 1324  0
             return _name;
 1325  
         }
 1326  
 
 1327  
         public void setName(String name)
 1328  
         {
 1329  0
             _name = name;
 1330  0
         }
 1331  
 
 1332  
         public Object getValue()
 1333  
         {
 1334  0
             return _value;
 1335  
         }
 1336  
 
 1337  
         public void setValue(Object value)
 1338  
         {
 1339  0
             _value = value;
 1340  0
         }
 1341  
     }
 1342  
 
 1343  
     public static void renderHiddenCommandFormParams(ResponseWriter writer,
 1344  
             Set dummyFormParams) throws IOException
 1345  
     {
 1346  0
         for (Iterator it = dummyFormParams.iterator(); it.hasNext();)
 1347  
         {
 1348  0
             Object name = it.next();
 1349  0
             renderHiddenInputField(writer, name, null);
 1350  0
         }
 1351  0
     }
 1352  
 
 1353  
     public static void renderHiddenInputField(ResponseWriter writer,
 1354  
             Object name, Object value) throws IOException
 1355  
     {
 1356  0
         writer.startElement(HTML.INPUT_ELEM, null);
 1357  0
         writer.writeAttribute(HTML.TYPE_ATTR, HTML.INPUT_TYPE_HIDDEN, null);
 1358  0
         writer.writeAttribute(HTML.NAME_ATTR, name, null);
 1359  0
         if (value != null)
 1360  
         {
 1361  0
             writer.writeAttribute(HTML.VALUE_ATTR, value, null);
 1362  
         }
 1363  0
         writer.endElement(HTML.INPUT_ELEM);
 1364  0
     }
 1365  
 
 1366  
     /**
 1367  
      * @deprecated Replaced by
 1368  
      *             renderLabel(ResponseWriter writer,
 1369  
      *             UIComponent component,
 1370  
      *             String forClientId,
 1371  
      *             SelectItem item,
 1372  
      *             boolean disabled).
 1373  
      *             Renders a label HTML element
 1374  
      */
 1375  
     @Deprecated
 1376  
     public static void renderLabel(ResponseWriter writer,
 1377  
             UIComponent component, String forClientId, String labelValue,
 1378  
             boolean disabled) throws IOException
 1379  
     {
 1380  0
         writer.startElement(HTML.LABEL_ELEM, null); // component);
 1381  0
         writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
 1382  0
         String labelClass = null;
 1383  0
         if (disabled)
 1384  
         {
 1385  0
             labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 1386  
         }
 1387  
         else
 1388  
         {
 1389  0
             labelClass = (String) component.getAttributes()
 1390  
                     .get(org.apache.myfaces.shared.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
 1391  
         }
 1392  0
         if (labelClass != null)
 1393  
         {
 1394  0
             writer.writeAttribute("class", labelClass, "labelClass");
 1395  
         }
 1396  0
         if ((labelValue != null) && (labelValue.length() > 0))
 1397  
         {
 1398  0
             writer.write(HTML.NBSP_ENTITY);
 1399  0
             writer.writeText(labelValue, null);
 1400  
         }
 1401  0
         writer.endElement(HTML.LABEL_ELEM);
 1402  0
     }
 1403  
 
 1404  
     /**
 1405  
      * Renders a label HTML element
 1406  
      */
 1407  
     public static void renderLabel(ResponseWriter writer,
 1408  
             UIComponent component, String forClientId, SelectItem item,
 1409  
             boolean disabled) throws IOException
 1410  
     {
 1411  0
         writer.startElement(HTML.LABEL_ELEM, null); // component);
 1412  0
         writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
 1413  0
         String labelClass = null;
 1414  0
         if (disabled)
 1415  
         {
 1416  0
             labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 1417  
         }
 1418  
         else
 1419  
         {
 1420  0
             labelClass = (String) component.getAttributes()
 1421  
                     .get(org.apache.myfaces.shared.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
 1422  
         }
 1423  0
         if (labelClass != null)
 1424  
         {
 1425  0
             writer.writeAttribute("class", labelClass, "labelClass");
 1426  
         }
 1427  0
         if ((item.getLabel() != null) && (item.getLabel().length() > 0))
 1428  
         {
 1429  
             // writer.write(HTML.NBSP_ENTITY);
 1430  0
             writer.write(" ");
 1431  0
             if (item.isEscape())
 1432  
             {
 1433  
                 //writer.write(item.getLabel());
 1434  0
                 writer.writeText(item.getLabel(), null);
 1435  
             }
 1436  
             else
 1437  
             {
 1438  
                 //writer.write(HTMLEncoder.encode (item.getLabel()));
 1439  0
                 writer.write(item.getLabel());
 1440  
             }
 1441  
         }
 1442  0
         writer.endElement(HTML.LABEL_ELEM);
 1443  0
     }
 1444  
 
 1445  
     /**
 1446  
      * Renders a label HTML element
 1447  
      */
 1448  
     public static void renderLabel(ResponseWriter writer,
 1449  
             UIComponent component, String forClientId, SelectItem item,
 1450  
             boolean disabled, boolean selected) throws IOException
 1451  
     {
 1452  0
         writer.startElement(HTML.LABEL_ELEM, null); // component);
 1453  0
         writer.writeAttribute(HTML.FOR_ATTR, forClientId, null);
 1454  0
         String labelClass = null;
 1455  0
         if (disabled)
 1456  
         {
 1457  0
             labelClass = (String) component.getAttributes().get(JSFAttr.DISABLED_CLASS_ATTR);
 1458  
         }
 1459  
         else
 1460  
         {
 1461  0
             labelClass = (String) component.getAttributes()
 1462  
                     .get(org.apache.myfaces.shared.renderkit.JSFAttr.ENABLED_CLASS_ATTR);
 1463  
         }
 1464  0
         String labelSelectedClass = null;
 1465  0
         if (selected)
 1466  
         {
 1467  0
             labelSelectedClass = (String) component.getAttributes().get(JSFAttr.SELECTED_CLASS_ATTR);
 1468  
         }
 1469  
         else
 1470  
         {
 1471  0
             labelSelectedClass = (String) component.getAttributes().get(JSFAttr.UNSELECTED_CLASS_ATTR);
 1472  
         }
 1473  0
         if (labelSelectedClass != null)
 1474  
         {
 1475  0
             if (labelClass == null)
 1476  
             {
 1477  0
                 labelClass = labelSelectedClass;
 1478  
             }
 1479  
             else
 1480  
             {
 1481  0
                 labelClass = labelClass + " " + labelSelectedClass;
 1482  
             }
 1483  
         }
 1484  0
         if (labelClass != null)
 1485  
         {
 1486  0
             writer.writeAttribute("class", labelClass, "labelClass");
 1487  
         }
 1488  0
         if ((item.getLabel() != null) && (item.getLabel().length() > 0))
 1489  
         {
 1490  0
             writer.write(HTML.NBSP_ENTITY);
 1491  0
             if (item.isEscape())
 1492  
             {
 1493  
                 //writer.write(item.getLabel());
 1494  0
                 writer.writeText(item.getLabel(), null);
 1495  
             }
 1496  
             else
 1497  
             {
 1498  
                 //writer.write(HTMLEncoder.encode (item.getLabel()));
 1499  0
                 writer.write(item.getLabel());
 1500  
             }
 1501  
         }
 1502  0
         writer.endElement(HTML.LABEL_ELEM);
 1503  0
     }
 1504  
 
 1505  
     /**
 1506  
      * Render the javascript function that is called on a click on a commandLink
 1507  
      * to clear the hidden inputs. This is necessary because on a browser back,
 1508  
      * each hidden input still has it's old value (browser cache!) and therefore
 1509  
      * a new submit would cause the according action once more!
 1510  
      *
 1511  
      * @param writer
 1512  
      * @param formName
 1513  
      * @param dummyFormParams
 1514  
      * @param formTarget
 1515  
      * @throws IOException
 1516  
      */
 1517  
     public static void renderClearHiddenCommandFormParamsFunction(
 1518  
             ResponseWriter writer, String formName, Set dummyFormParams,
 1519  
             String formTarget) throws IOException
 1520  
     {
 1521  0
         HtmlJavaScriptUtils.renderClearHiddenCommandFormParamsFunction(writer, formName, dummyFormParams, formTarget);
 1522  0
     }
 1523  
 
 1524  
     /**
 1525  
      * Prefixes the given String with "clear_" and removes special characters
 1526  
      *
 1527  
      * @param formName
 1528  
      * @return String
 1529  
      */
 1530  
     public static String getClearHiddenCommandFormParamsFunctionName(
 1531  
             String formName)
 1532  
     {
 1533  0
         return HtmlJavaScriptUtils.getClearHiddenCommandFormParamsFunctionName(formName);
 1534  
     }
 1535  
 
 1536  
     public static String getClearHiddenCommandFormParamsFunctionNameMyfacesLegacy(
 1537  
             String formName)
 1538  
     {
 1539  0
         return HtmlJavaScriptUtils.getClearHiddenCommandFormParamsFunctionNameMyfacesLegacy(formName);
 1540  
     }
 1541  
 
 1542  
     /**
 1543  
      * Get the name of the request parameter that holds the id of the
 1544  
      * link-type component that caused the form to be submitted.
 1545  
      * <p/>
 1546  
      * Within each page there may be multiple "link" type components that
 1547  
      * cause page submission. On the server it is necessary to know which
 1548  
      * of these actually caused the submit, in order to invoke the correct
 1549  
      * listeners. Such components therefore store their id into the
 1550  
      * "hidden command link field" in their associated form before
 1551  
      * submitting it.
 1552  
      * <p/>
 1553  
      * The field is always a direct child of each form, and has the same
 1554  
      * <i>name</i> in each form. The id of the form component is therefore
 1555  
      * both necessary and sufficient to determine the full name of the
 1556  
      * field.
 1557  
      */
 1558  
     public static String getHiddenCommandLinkFieldName(FormInfo formInfo)
 1559  
     {
 1560  0
         if (RendererUtils.isAdfOrTrinidadForm(formInfo.getForm()))
 1561  
         {
 1562  0
             return HIDDEN_COMMANDLINK_FIELD_NAME_TRINIDAD;
 1563  
         }
 1564  0
         return formInfo.getFormName() + ':' 
 1565  
                 + HIDDEN_COMMANDLINK_FIELD_NAME;
 1566  
     }
 1567  
     
 1568  
     public static String getHiddenCommandLinkFieldName(
 1569  
             FormInfo formInfo, FacesContext facesContext)
 1570  
     {
 1571  0
         if (RendererUtils.isAdfOrTrinidadForm(formInfo.getForm()))
 1572  
         {
 1573  0
             return HIDDEN_COMMANDLINK_FIELD_NAME_TRINIDAD;
 1574  
         }
 1575  0
         return formInfo.getFormName() + ':'
 1576  
                 + HIDDEN_COMMANDLINK_FIELD_NAME;
 1577  
     }
 1578  
 
 1579  
     public static boolean isPartialOrBehaviorSubmit(FacesContext facesContext,
 1580  
             String clientId)
 1581  
     {
 1582  0
         Map<String, String> params = facesContext.getExternalContext().getRequestParameterMap();
 1583  0
         String sourceId = params.get("javax.faces.source");
 1584  0
         if (sourceId == null || !sourceId.equals(clientId))
 1585  
         {
 1586  0
             return false;
 1587  
         }
 1588  0
         boolean partialOrBehaviorSubmit = false;
 1589  0
         String behaviorEvent = params.get("javax.faces.behavior.event");
 1590  0
         if (behaviorEvent != null)
 1591  
         {
 1592  0
             partialOrBehaviorSubmit = ClientBehaviorEvents.ACTION.equals(behaviorEvent);
 1593  0
             if (partialOrBehaviorSubmit)
 1594  
             {
 1595  0
                 return partialOrBehaviorSubmit;
 1596  
             }
 1597  
         }
 1598  0
         String partialEvent = params.get("javax.faces.partial.event");
 1599  0
         if (partialEvent != null)
 1600  
         {
 1601  0
             partialOrBehaviorSubmit = ClientBehaviorEvents.CLICK.equals(partialEvent);
 1602  
         }
 1603  0
         return partialOrBehaviorSubmit;
 1604  
     }
 1605  
 
 1606  
     public static String getHiddenCommandLinkFieldNameMyfacesOld(
 1607  
             FormInfo formInfo)
 1608  
     {
 1609  0
         return formInfo.getFormName() + ':'
 1610  
                 + HIDDEN_COMMANDLINK_FIELD_NAME_MYFACES_OLD;
 1611  
     }
 1612  
 
 1613  
     public static String getOutcomeTargetHref(FacesContext facesContext,
 1614  
             UIOutcomeTarget component) throws IOException
 1615  
     {
 1616  0
         return OutcomeTargetUtils.getOutcomeTargetHref(facesContext, component);
 1617  
     }
 1618  
 
 1619  
     private static final String HTML_CONTENT_TYPE = "text/html";
 1620  
     private static final String TEXT_ANY_CONTENT_TYPE = "text/*";
 1621  
     private static final String ANY_CONTENT_TYPE = "*/*";
 1622  
     public static final String DEFAULT_CHAR_ENCODING = "ISO-8859-1";
 1623  
     private static final String XHTML_CONTENT_TYPE = "application/xhtml+xml";
 1624  
     private static final String APPLICATION_XML_CONTENT_TYPE = "application/xml";
 1625  
     private static final String TEXT_XML_CONTENT_TYPE = "text/xml";
 1626  
     // The order is important in this case.
 1627  1
     private static final String[] SUPPORTED_CONTENT_TYPES = {
 1628  
             HTML_CONTENT_TYPE, //Prefer this over any other, because IE does not support XHTML content type
 1629  
             XHTML_CONTENT_TYPE, APPLICATION_XML_CONTENT_TYPE,
 1630  
             TEXT_XML_CONTENT_TYPE, TEXT_ANY_CONTENT_TYPE, ANY_CONTENT_TYPE };
 1631  
     /**
 1632  
      * @deprecated use ContentTypeUtils instead
 1633  
      */
 1634  
     @Deprecated
 1635  
     public static String selectContentType(String contentTypeListString)
 1636  
     {
 1637  0
         if (contentTypeListString == null)
 1638  
         {
 1639  0
             FacesContext context = FacesContext.getCurrentInstance();
 1640  0
             if (context != null)
 1641  
             {
 1642  0
                 contentTypeListString = (String) context.getExternalContext()
 1643  
                         .getRequestHeaderMap().get("Accept");
 1644  
                 // There is a windows mobile IE client (6.12) sending
 1645  
                 // "application/vnd.wap.mms-message;*/*"
 1646  
                 // Note that the Accept header should be written as 
 1647  
                 // "application/vnd.wap.mms-message,*/*" ,
 1648  
                 // so this is bug of the client. Anyway, this is a workaround ...
 1649  0
                 if (contentTypeListString != null
 1650  
                         && contentTypeListString.startsWith("application/vnd.wap.mms-message;*/*"))
 1651  
                 {
 1652  0
                     contentTypeListString = "*/*";
 1653  
                 }
 1654  
             }
 1655  0
             if (contentTypeListString == null)
 1656  
             {
 1657  0
                 if (log.isLoggable(Level.FINE))
 1658  
                 {
 1659  0
                     log.fine("No content type list given, creating HtmlResponseWriterImpl with default content type.");
 1660  
                 }
 1661  0
                 contentTypeListString = HTML_CONTENT_TYPE;
 1662  
             }
 1663  
         }
 1664  0
         List contentTypeList = splitContentTypeListString(contentTypeListString);
 1665  0
         String[] supportedContentTypeArray = getSupportedContentTypes();
 1666  0
         String selectedContentType = null;
 1667  0
         for (int i = 0; i < supportedContentTypeArray.length; i++)
 1668  
         {
 1669  0
             String supportedContentType = supportedContentTypeArray[i].trim();
 1670  
 
 1671  0
             for (int j = 0; j < contentTypeList.size(); j++)
 1672  
             {
 1673  0
                 String contentType = (String) contentTypeList.get(j);
 1674  
 
 1675  0
                 if (contentType.indexOf(supportedContentType) != -1)
 1676  
                 {
 1677  0
                     if (isHTMLContentType(contentType))
 1678  
                     {
 1679  0
                         selectedContentType = HTML_CONTENT_TYPE;
 1680  
                     }
 1681  0
                     else if (isXHTMLContentType(contentType))
 1682  
                     {
 1683  0
                         selectedContentType = XHTML_CONTENT_TYPE;
 1684  
                     }
 1685  
                     break;
 1686  
                 }
 1687  
             }
 1688  0
             if (selectedContentType != null)
 1689  
             {
 1690  0
                 break;
 1691  
             }
 1692  
         }
 1693  0
         if (selectedContentType == null)
 1694  
         {
 1695  0
             throw new IllegalArgumentException(
 1696  
                     "ContentTypeList does not contain a supported content type: "
 1697  
                             + contentTypeListString);
 1698  
         }
 1699  0
         return selectedContentType;
 1700  
     }
 1701  
 
 1702  
     public static String[] getSupportedContentTypes()
 1703  
     {
 1704  
         //String[] supportedContentTypeArray = new String[]{
 1705  
         // HTML_CONTENT_TYPE,TEXT_ANY_CONTENT_TYPE,ANY_CONTENT_TYPE,
 1706  
         // XHTML_CONTENT_TYPE,APPLICATION_XML_CONTENT_TYPE,TEXT_XML_CONTENT_TYPE};
 1707  0
         return SUPPORTED_CONTENT_TYPES;
 1708  
     }
 1709  
 
 1710  
     private static boolean isHTMLContentType(String contentType)
 1711  
     {
 1712  0
         return contentType.indexOf(HTML_CONTENT_TYPE) != -1
 1713  
                 || contentType.indexOf(ANY_CONTENT_TYPE) != -1
 1714  
                 || contentType.indexOf(TEXT_ANY_CONTENT_TYPE) != -1;
 1715  
     }
 1716  
 
 1717  
     public static boolean isXHTMLContentType(String contentType)
 1718  
     {
 1719  23
         return contentType.indexOf(XHTML_CONTENT_TYPE) != -1
 1720  
                 || contentType.indexOf(APPLICATION_XML_CONTENT_TYPE) != -1
 1721  
                 || contentType.indexOf(TEXT_XML_CONTENT_TYPE) != -1;
 1722  
     }
 1723  
 
 1724  
     private static List splitContentTypeListString(String contentTypeListString)
 1725  
     {
 1726  0
         List contentTypeList = new ArrayList();
 1727  0
         StringTokenizer st = new StringTokenizer(contentTypeListString, ",");
 1728  0
         while (st.hasMoreTokens())
 1729  
         {
 1730  0
             String contentType = st.nextToken().trim();
 1731  0
             int semicolonIndex = contentType.indexOf(';');
 1732  0
             if (semicolonIndex != -1)
 1733  
             {
 1734  0
                 contentType = contentType.substring(0, semicolonIndex);
 1735  
             }
 1736  0
             contentTypeList.add(contentType);
 1737  0
         }
 1738  0
         return contentTypeList;
 1739  
     }
 1740  
 
 1741  
     public static String getJavascriptLocation(UIComponent component)
 1742  
     {
 1743  0
         if (component == null)
 1744  
         {
 1745  0
             return null;
 1746  
         }
 1747  0
         return (String) component.getAttributes().get(JSFAttr.JAVASCRIPT_LOCATION);
 1748  
     }
 1749  
 
 1750  
     public static String getImageLocation(UIComponent component)
 1751  
     {
 1752  0
         if (component == null)
 1753  
         {
 1754  0
             return null;
 1755  
         }
 1756  0
         return (String) component.getAttributes().get(JSFAttr.IMAGE_LOCATION);
 1757  
     }
 1758  
 
 1759  
     public static String getStyleLocation(UIComponent component)
 1760  
     {
 1761  0
         if (component == null)
 1762  
         {
 1763  0
             return null;
 1764  
         }
 1765  0
         return (String) component.getAttributes().get(JSFAttr.STYLE_LOCATION);
 1766  
     }
 1767  
 
 1768  
     /**
 1769  
      * Checks if the given component has a behavior attachment with a given name.
 1770  
      *
 1771  
      * @param eventName the event name to be checked for
 1772  
      * @param behaviors map of behaviors attached to the component
 1773  
      * @return true if client behavior with given name is attached, false otherwise
 1774  
      * @since 4.0.0
 1775  
      */
 1776  
     public static boolean hasClientBehavior(String eventName,
 1777  
             Map<String, List<ClientBehavior>> behaviors,
 1778  
             FacesContext facesContext)
 1779  
     {
 1780  0
         if (behaviors == null)
 1781  
         {
 1782  0
             return false;
 1783  
         }
 1784  0
         return (behaviors.get(eventName) != null);
 1785  
     }
 1786  
 
 1787  
     public static Collection<ClientBehaviorContext.Parameter> getClientBehaviorContextParameters(
 1788  
             Map<String, String> params)
 1789  
     {
 1790  0
         List<ClientBehaviorContext.Parameter> paramList = null;
 1791  0
         if (params != null)
 1792  
         {
 1793  0
             paramList = new ArrayList<ClientBehaviorContext.Parameter>(params.size());
 1794  0
             for (Map.Entry<String, String> paramEntry : params.entrySet())
 1795  
             {
 1796  0
                 paramList.add(new ClientBehaviorContext.Parameter(paramEntry
 1797  
                         .getKey(), paramEntry.getValue()));
 1798  0
             }
 1799  
         }
 1800  0
         return paramList;
 1801  
     }
 1802  
 
 1803  
     /**
 1804  
      * builds the chained behavior script which then can be reused
 1805  
      * in following order by the other script building parts
 1806  
      * <p/>
 1807  
      * user defined event handling script
 1808  
      * behavior script
 1809  
      * renderer default script
 1810  
      *
 1811  
      * @param eventName    event name ("onclick" etc...)
 1812  
      * @param uiComponent  the component which has the attachement (or should have)
 1813  
      * @param facesContext the facesContext
 1814  
      * @param params       params map of params which have to be dragged into the request
 1815  
      * @return a string representation of the javascripts for the attached event behavior,
 1816  
      *         an empty string if none is present
 1817  
      * @since 4.0.0
 1818  
      */
 1819  
     private static boolean getClientBehaviorScript(FacesContext facesContext,
 1820  
             UIComponent uiComponent, String sourceId, String eventName,
 1821  
             Map<String, List<ClientBehavior>> clientBehaviors,
 1822  
             ScriptContext target,
 1823  
             Collection<ClientBehaviorContext.Parameter> params)
 1824  
     {
 1825  12
         if (!(uiComponent instanceof ClientBehaviorHolder))
 1826  
         {
 1827  0
             target.append(STR_EMPTY);
 1828  0
             return false;
 1829  
         }
 1830  12
         boolean renderClientBehavior = clientBehaviors != null && clientBehaviors.size() > 0;
 1831  12
         if (!renderClientBehavior)
 1832  
         {
 1833  8
             target.append(STR_EMPTY);
 1834  8
             return false;
 1835  
         }
 1836  4
         List<ClientBehavior> attachedEventBehaviors = clientBehaviors
 1837  
                 .get(eventName);
 1838  4
         if (attachedEventBehaviors == null
 1839  
                 || attachedEventBehaviors.size() == 0)
 1840  
         {
 1841  2
             target.append(STR_EMPTY);
 1842  2
             return false;
 1843  
         }
 1844  2
         ClientBehaviorContext context = ClientBehaviorContext
 1845  
                 .createClientBehaviorContext(facesContext, uiComponent,
 1846  
                         eventName, sourceId, params);
 1847  2
         boolean submitting = false;
 1848  
         
 1849  
         // List<ClientBehavior>  attachedEventBehaviors is  99% _DeltaList created in
 1850  
         // javax.faces.component.UIComponentBase.addClientBehavior
 1851  2
         if (attachedEventBehaviors instanceof RandomAccess)
 1852  
         {
 1853  4
             for (int i = 0, size = attachedEventBehaviors.size(); i < size; i++)
 1854  
             {
 1855  2
                 ClientBehavior clientBehavior = attachedEventBehaviors.get(i);
 1856  2
                 submitting =  _appendClientBehaviourScript(target, context, 
 1857  
                         submitting, i < (size -1), clientBehavior);   
 1858  
             }
 1859  
         }
 1860  
         else 
 1861  
         {
 1862  0
             Iterator<ClientBehavior> clientIterator = attachedEventBehaviors.iterator();
 1863  0
             while (clientIterator.hasNext())
 1864  
             {
 1865  0
                 ClientBehavior clientBehavior = clientIterator.next();
 1866  0
                 submitting = _appendClientBehaviourScript(target, context, submitting, 
 1867  
                         clientIterator.hasNext(), clientBehavior);
 1868  0
             }
 1869  
         }
 1870  
         
 1871  2
         return submitting;
 1872  
     }
 1873  
 
 1874  
     private static boolean _appendClientBehaviourScript(ScriptContext target, ClientBehaviorContext context, 
 1875  
             boolean submitting, boolean hasNext, ClientBehavior clientBehavior)
 1876  
     {
 1877  2
         String script = clientBehavior.getScript(context);
 1878  
         // The script _can_ be null, and in fact is for <f:ajax disabled="true" />
 1879  2
         if (script != null)
 1880  
         {
 1881  
             //either strings or functions, but I assume string is more appropriate 
 1882  
             //since it allows access to the
 1883  
             //origin as this!
 1884  2
             target.append("'" + escapeJavaScriptForChain(script) + "'");
 1885  2
             if (hasNext)
 1886  
             {
 1887  0
                 target.append(", ");
 1888  
             }
 1889  
         }
 1890  
         // MYFACES-3836 If no script provided by the client behavior, ignore the 
 1891  
         // submitting hint because. it is evidence the client behavior is disabled.
 1892  2
         if (script != null && !submitting)
 1893  
         {
 1894  2
             submitting = clientBehavior.getHints().contains(
 1895  
                     ClientBehaviorHint.SUBMITTING);
 1896  
         }
 1897  2
         return submitting;
 1898  
     }
 1899  
 
 1900  
     /**
 1901  
      * @since 4.0.0
 1902  
      */
 1903  
     public static String buildBehaviorChain(FacesContext facesContext,
 1904  
             UIComponent uiComponent, String eventName,
 1905  
             Collection<ClientBehaviorContext.Parameter> params,
 1906  
             Map<String, List<ClientBehavior>> clientBehaviors,
 1907  
             String userEventCode, String serverEventCode)
 1908  
     {
 1909  0
         return buildBehaviorChain(facesContext, uiComponent,
 1910  
                 null, eventName, params,
 1911  
                 clientBehaviors, userEventCode, serverEventCode);
 1912  
     }
 1913  
 
 1914  
     public static String buildBehaviorChain(FacesContext facesContext,
 1915  
             UIComponent uiComponent, String sourceId, String eventName,
 1916  
             Collection<ClientBehaviorContext.Parameter> params,
 1917  
             Map<String, List<ClientBehavior>> clientBehaviors,
 1918  
             String userEventCode, String serverEventCode)
 1919  
     {
 1920  0
         List<String> finalParams = new ArrayList<String>(3);
 1921  0
         if (userEventCode != null && !userEventCode.trim().equals(STR_EMPTY))
 1922  
         {
 1923  
             // escape every ' in the user event code since it will
 1924  
             // be a string attribute of jsf.util.chain
 1925  0
             finalParams.add('\'' + escapeJavaScriptForChain(userEventCode) + '\'');
 1926  
         }
 1927  0
         ScriptContext behaviorCode = new ScriptContext();
 1928  0
         ScriptContext retVal = new ScriptContext();
 1929  0
         getClientBehaviorScript(facesContext, uiComponent, sourceId,
 1930  
                 eventName, clientBehaviors, behaviorCode, params);
 1931  0
         if (behaviorCode != null
 1932  
                 && !behaviorCode.toString().trim().equals(STR_EMPTY))
 1933  
         {
 1934  0
             finalParams.add(behaviorCode.toString());
 1935  
         }
 1936  0
         if (serverEventCode != null
 1937  
                 && !serverEventCode.trim().equals(STR_EMPTY))
 1938  
         {
 1939  0
             finalParams
 1940  
                     .add('\'' + escapeJavaScriptForChain(serverEventCode) + '\'');
 1941  
         }
 1942  0
         Iterator<String> it = finalParams.iterator();
 1943  
         // It's possible that there are no behaviors to render.  For example, if we have
 1944  
         // <f:ajax disabled="true" /> as the only behavior.
 1945  0
         if (it.hasNext())
 1946  
         {
 1947  
             //according to the spec jsf.util.chain has to be used to build up the 
 1948  
             //behavior and scripts
 1949  0
             if (sourceId == null)
 1950  
             {
 1951  0
                 retVal.append("jsf.util.chain(this, event,");
 1952  
             }
 1953  
             else
 1954  
             {
 1955  0
                 retVal.append("jsf.util.chain(document.getElementById('"
 1956  
                         + sourceId + "'), event,");
 1957  
             }
 1958  0
             while (it.hasNext())
 1959  
             {
 1960  0
                 retVal.append(it.next());
 1961  0
                 if (it.hasNext())
 1962  
                 {
 1963  0
                     retVal.append(", ");
 1964  
                 }
 1965  
             }
 1966  0
             retVal.append(");");
 1967  
         }
 1968  
 
 1969  0
         return retVal.toString();
 1970  
     }
 1971  
 
 1972  
     /**
 1973  
      * @param facesContext
 1974  
      * @param uiComponent
 1975  
      * @param clientBehaviors
 1976  
      * @param eventName1
 1977  
      * @param eventName2
 1978  
      * @param userEventCode
 1979  
      * @param serverEventCode
 1980  
      * @param params
 1981  
      * @return
 1982  
      * @since 4.0.0
 1983  
      */
 1984  
     public static String buildBehaviorChain(FacesContext facesContext,
 1985  
             UIComponent uiComponent, String eventName1,
 1986  
             Collection<ClientBehaviorContext.Parameter> params,
 1987  
             String eventName2,
 1988  
             Collection<ClientBehaviorContext.Parameter> params2,
 1989  
             Map<String, List<ClientBehavior>> clientBehaviors,
 1990  
             String userEventCode, String serverEventCode)
 1991  
     {
 1992  3
         return buildBehaviorChain(facesContext, uiComponent,
 1993  
                 null, eventName1, params,
 1994  
                 eventName2, params2, clientBehaviors, userEventCode,
 1995  
                 serverEventCode);
 1996  
     }
 1997  
 
 1998  
     public static String buildBehaviorChain(FacesContext facesContext,
 1999  
             UIComponent uiComponent, String sourceId, String eventName1,
 2000  
             Collection<ClientBehaviorContext.Parameter> params,
 2001  
             String eventName2,
 2002  
             Collection<ClientBehaviorContext.Parameter> params2,
 2003  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2004  
             String userEventCode, String serverEventCode)
 2005  
     {
 2006  6
         ExternalContext externalContext = facesContext.getExternalContext();
 2007  6
         List<String> finalParams = new ArrayList<String>(3);
 2008  6
         if (userEventCode != null && !userEventCode.trim().equals(STR_EMPTY))
 2009  
         {
 2010  4
             finalParams.add('\'' + escapeJavaScriptForChain(userEventCode) + '\'');
 2011  
         }
 2012  
 
 2013  6
         ScriptContext behaviorCode = new ScriptContext();
 2014  6
         ScriptContext retVal = new ScriptContext();
 2015  6
         boolean submitting1 = getClientBehaviorScript(facesContext,
 2016  
                 uiComponent, sourceId, eventName1, clientBehaviors,
 2017  
                 behaviorCode, params);
 2018  6
         ScriptContext behaviorCode2 = new ScriptContext();
 2019  6
         boolean submitting2 = getClientBehaviorScript(facesContext,
 2020  
                 uiComponent, sourceId, eventName2, clientBehaviors,
 2021  
                 behaviorCode2, params2);
 2022  
 
 2023  
         // ClientBehaviors for both events have to be checked for the Submitting hint
 2024  6
         boolean submitting = submitting1 || submitting2;
 2025  6
         if (behaviorCode != null
 2026  
                 && !behaviorCode.toString().trim().equals(STR_EMPTY))
 2027  
         {
 2028  2
             finalParams.add(behaviorCode.toString());
 2029  
         }
 2030  6
         if (behaviorCode2 != null
 2031  
                 && !behaviorCode2.toString().trim().equals(STR_EMPTY))
 2032  
         {
 2033  0
             finalParams.add(behaviorCode2.toString());
 2034  
         }
 2035  6
         if (serverEventCode != null
 2036  
                 && !serverEventCode.trim().equals(STR_EMPTY))
 2037  
         {
 2038  4
             finalParams.add('\'' + escapeJavaScriptForChain(serverEventCode) + '\'');
 2039  
         }
 2040  
         
 2041  
         // It's possible that there are no behaviors to render.  For example, if we have
 2042  
         // <f:ajax disabled="true" /> as the only behavior.
 2043  
         
 2044  6
         int size = finalParams.size();
 2045  6
         if (size > 0)
 2046  
         {
 2047  4
             if (!submitting)
 2048  
             {
 2049  2
                 retVal.append("return ");
 2050  
             }
 2051  
             //according to the spec jsf.util.chain has to be used to build up the 
 2052  
             //behavior and scripts
 2053  4
             if (sourceId == null)
 2054  
             {
 2055  2
                 retVal.append("jsf.util.chain(this, event,");
 2056  
             }
 2057  
             else
 2058  
             {
 2059  2
                 retVal.append("jsf.util.chain(document.getElementById('"
 2060  
                         + sourceId + "'), event,");
 2061  
             }
 2062  4
             int cursor = 0;
 2063  14
             while (cursor != size)
 2064  
             {
 2065  10
                 retVal.append(finalParams.get(cursor));
 2066  10
                 cursor++;
 2067  10
                 if (cursor != size)
 2068  
                 {
 2069  6
                     retVal.append(", ");
 2070  
                 }
 2071  
             }
 2072  4
             retVal.append(");");
 2073  4
             if (submitting)
 2074  
             {
 2075  2
                 retVal.append(" return false;");
 2076  
             }
 2077  
         }
 2078  
 
 2079  6
         return retVal.toString();
 2080  
 
 2081  
     }
 2082  
 
 2083  
     /**
 2084  
      * This function correctly escapes the given JavaScript code
 2085  
      * for the use in the jsf.util.chain() JavaScript function.
 2086  
      * It also handles double-escaping correclty.
 2087  
      *
 2088  
      * @param javaScript
 2089  
      * @return
 2090  
      */
 2091  
     public static String escapeJavaScriptForChain(String javaScript)
 2092  
     {
 2093  13
         return HtmlJavaScriptUtils.escapeJavaScriptForChain(javaScript);
 2094  
     }
 2095  
 
 2096  
     public static Map<String, String> mapAttachedParamsToStringValues(
 2097  
             FacesContext facesContext, UIComponent uiComponent)
 2098  
     {
 2099  0
         Map<String, String> retVal = null;
 2100  0
         if (uiComponent.getChildCount() > 0)
 2101  
         {
 2102  0
             List<UIParameter> validParams = getValidUIParameterChildren(
 2103  
                     facesContext, uiComponent.getChildren(), true, true);
 2104  0
             for (int i = 0, size = validParams.size(); i < size; i++)
 2105  
             {
 2106  0
                 UIParameter param = validParams.get(i);
 2107  0
                 String name = param.getName();
 2108  0
                 Object value = param.getValue();
 2109  0
                 if (retVal == null)
 2110  
                 {
 2111  0
                     retVal = new HashMap<String, String>();
 2112  
                 }
 2113  0
                 if (value instanceof String)
 2114  
                 {
 2115  0
                     retVal.put(name, (String) value);
 2116  
                 }
 2117  
                 else
 2118  
                 {
 2119  0
                     retVal.put(name, value.toString());
 2120  
                 }
 2121  
             }
 2122  
         }
 2123  0
         if (retVal == null)
 2124  
         {
 2125  0
             retVal = Collections.emptyMap();
 2126  
         }
 2127  0
         return retVal;
 2128  
     }
 2129  
 
 2130  
     /**
 2131  
      * Calls getValidUIParameterChildren(facesContext, children, skipNullValue, skipUnrendered, true);
 2132  
      *
 2133  
      * @param facesContext
 2134  
      * @param children
 2135  
      * @param skipNullValue
 2136  
      * @param skipUnrendered
 2137  
      * @return ArrayList size > 0 if any parameter found
 2138  
      */
 2139  
     public static List<UIParameter> getValidUIParameterChildren(
 2140  
             FacesContext facesContext, List<UIComponent> children,
 2141  
             boolean skipNullValue, boolean skipUnrendered)
 2142  
     {
 2143  0
         return getValidUIParameterChildren(facesContext, children,
 2144  
                 skipNullValue, skipUnrendered, true);
 2145  
     }
 2146  
 
 2147  
     /**
 2148  
      * Returns a List of all valid UIParameter children from the given children.
 2149  
      * Valid means that the UIParameter is not disabled, its name is not null
 2150  
      * (if skipNullName is true), its value is not null (if skipNullValue is true)
 2151  
      * and it is rendered (if skipUnrendered is true). This method also creates a
 2152  
      * warning for every UIParameter with a null-name (again, if skipNullName is true)
 2153  
      * and, if ProjectStage is Development and skipNullValue is true, it informs the
 2154  
      * user about every null-value.
 2155  
      *
 2156  
      * @param facesContext
 2157  
      * @param children
 2158  
      * @param skipNullValue  should UIParameters with a null value be skipped
 2159  
      * @param skipUnrendered should UIParameters with isRendered() returning false be skipped
 2160  
      * @param skipNullName   should UIParameters with a null name be skipped
 2161  
      *                       (normally true, but in the case of h:outputFormat false)
 2162  
      * @return ArrayList size > 0 if any parameter found 
 2163  
      */
 2164  
     public static List<UIParameter> getValidUIParameterChildren(
 2165  
             FacesContext facesContext, List<UIComponent> children,
 2166  
             boolean skipNullValue, boolean skipUnrendered, boolean skipNullName)
 2167  
     {
 2168  0
         return OutcomeTargetUtils.getValidUIParameterChildren(
 2169  
             facesContext, children, skipNullValue, skipUnrendered, skipNullName);
 2170  
     }
 2171  
 
 2172  
     /**
 2173  
      * Render an attribute taking into account the passed event and
 2174  
      * the component property. It will be rendered as "componentProperty"
 2175  
      * attribute.
 2176  
      *
 2177  
      * @param facesContext
 2178  
      * @param writer
 2179  
      * @param componentProperty
 2180  
      * @param component
 2181  
      * @param eventName
 2182  
      * @param clientBehaviors
 2183  
      * @return
 2184  
      * @throws IOException
 2185  
      * @since 4.0.1
 2186  
      */
 2187  
     public static boolean renderBehaviorizedAttribute(
 2188  
             FacesContext facesContext, ResponseWriter writer,
 2189  
             String componentProperty, UIComponent component, String eventName,
 2190  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2191  
             throws IOException
 2192  
     {
 2193  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2194  
                 componentProperty, component, eventName, clientBehaviors, componentProperty);
 2195  
     }
 2196  
 
 2197  
     public static boolean renderBehaviorizedAttribute(
 2198  
             FacesContext facesContext, ResponseWriter writer,
 2199  
             String componentProperty, UIComponent component,
 2200  
             String sourceId, String eventName,
 2201  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2202  
             throws IOException
 2203  
     {
 2204  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2205  
                 componentProperty, component, sourceId, eventName, clientBehaviors, componentProperty);
 2206  
     }
 2207  
 
 2208  
     /**
 2209  
      * Render an attribute taking into account the passed event and
 2210  
      * the component property. The event will be rendered on the selected
 2211  
      * htmlAttrName
 2212  
      *
 2213  
      * @param facesContext
 2214  
      * @param writer
 2215  
      * @param component
 2216  
      * @param clientBehaviors
 2217  
      * @param eventName
 2218  
      * @param componentProperty
 2219  
      * @param htmlAttrName
 2220  
      * @return
 2221  
      * @throws IOException
 2222  
      * @since 4.0.1
 2223  
      */
 2224  
     public static boolean renderBehaviorizedAttribute(
 2225  
             FacesContext facesContext, ResponseWriter writer,
 2226  
             String componentProperty, UIComponent component, String eventName,
 2227  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2228  
             String htmlAttrName) throws IOException
 2229  
     {
 2230  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2231  
                 componentProperty, component, eventName, null, clientBehaviors,
 2232  
                 htmlAttrName, (String) component.getAttributes().get(componentProperty));
 2233  
     }
 2234  
 
 2235  
     public static boolean renderBehaviorizedAttribute(
 2236  
             FacesContext facesContext, ResponseWriter writer, String componentProperty, UIComponent component,
 2237  
             String sourceId, String eventName, Map<String, List<ClientBehavior>> clientBehaviors,
 2238  
             String htmlAttrName) throws IOException
 2239  
     {
 2240  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2241  
                 componentProperty, component, sourceId, eventName, null,
 2242  
                 clientBehaviors, htmlAttrName, (String) component.getAttributes().get(componentProperty));
 2243  
     }
 2244  
 
 2245  
     /**
 2246  
      * Render an attribute taking into account the passed event,
 2247  
      * the component property and the passed attribute value for the component
 2248  
      * property. The event will be rendered on the selected htmlAttrName.
 2249  
      *
 2250  
      * @param facesContext
 2251  
      * @param writer
 2252  
      * @param componentProperty
 2253  
      * @param component
 2254  
      * @param eventName
 2255  
      * @param clientBehaviors
 2256  
      * @param htmlAttrName
 2257  
      * @param attributeValue
 2258  
      * @return
 2259  
      * @throws IOException
 2260  
      */
 2261  
     public static boolean renderBehaviorizedAttribute(
 2262  
             FacesContext facesContext, ResponseWriter writer,
 2263  
             String componentProperty, UIComponent component, String eventName,
 2264  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2265  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2266  
             String htmlAttrName, String attributeValue) throws IOException
 2267  
     {
 2268  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2269  
                 componentProperty, component,
 2270  
                 null, eventName,
 2271  
                 eventParameters, clientBehaviors, htmlAttrName, attributeValue);
 2272  
     }
 2273  
 
 2274  
     public static boolean renderBehaviorizedAttribute(
 2275  
             FacesContext facesContext, ResponseWriter writer,
 2276  
             String componentProperty, UIComponent component,
 2277  
             String sourceId, String eventName,
 2278  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2279  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2280  
             String htmlAttrName, String attributeValue) throws IOException
 2281  
     {
 2282  
 
 2283  0
         List<ClientBehavior> cbl = (clientBehaviors != null) ? clientBehaviors
 2284  
                 .get(eventName) : null;
 2285  0
         if (cbl == null || cbl.size() == 0)
 2286  
         {
 2287  0
             return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
 2288  
                     attributeValue);
 2289  
         }
 2290  0
         if (cbl.size() > 1 || (cbl.size() == 1 && attributeValue != null))
 2291  
         {
 2292  0
             return renderHTMLAttribute(writer, componentProperty, htmlAttrName,
 2293  
                     HtmlRendererUtils.buildBehaviorChain(facesContext,
 2294  
                             component, sourceId, eventName,
 2295  
                             eventParameters, clientBehaviors, attributeValue,
 2296  
                             STR_EMPTY));
 2297  
         }
 2298  
         else
 2299  
         {
 2300  
             //Only 1 behavior and attrValue == null, so just render it directly
 2301  0
             return renderHTMLAttribute(
 2302  
                     writer, componentProperty, htmlAttrName,
 2303  
                     cbl.get(0).getScript(
 2304  
                             ClientBehaviorContext.createClientBehaviorContext(
 2305  
                                     facesContext, component, eventName,
 2306  
                                     sourceId, eventParameters)));
 2307  
         }
 2308  
     }
 2309  
 
 2310  
     /**
 2311  
      * Render an attribute taking into account the passed event,
 2312  
      * the passed attribute value for the component property.
 2313  
      * and the specific server code.
 2314  
      * The event will be rendered on the selected htmlAttrName.
 2315  
      *
 2316  
      * @param facesContext
 2317  
      * @param writer
 2318  
      * @param componentProperty
 2319  
      * @param component
 2320  
      * @param eventName
 2321  
      * @param clientBehaviors
 2322  
      * @param htmlAttrName
 2323  
      * @param attributeValue
 2324  
      * @param serverSideScript
 2325  
      * @return
 2326  
      * @throws IOException
 2327  
      */
 2328  
     public static boolean renderBehaviorizedAttribute(
 2329  
             FacesContext facesContext, ResponseWriter writer,
 2330  
             String componentProperty, UIComponent component, String eventName,
 2331  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2332  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2333  
             String htmlAttrName, String attributeValue, String serverSideScript)
 2334  
             throws IOException
 2335  
     {
 2336  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2337  
                 componentProperty, component,
 2338  
                 null, eventName,
 2339  
                 eventParameters, clientBehaviors, htmlAttrName, attributeValue,
 2340  
                 serverSideScript);
 2341  
     }
 2342  
 
 2343  
     // CHECKSTYLE:OFF
 2344  
     public static boolean renderBehaviorizedAttribute(
 2345  
             FacesContext facesContext, ResponseWriter writer,
 2346  
             String componentProperty, UIComponent component,
 2347  
             String sourceId, String eventName,
 2348  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2349  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2350  
             String htmlAttrName, String attributeValue, String serverSideScript)
 2351  
             throws IOException
 2352  
     {
 2353  
 
 2354  0
         List<ClientBehavior> cbl = (clientBehaviors != null) ? clientBehaviors
 2355  
                 .get(eventName) : null;
 2356  0
         if (((cbl != null) ? cbl.size() : 0) + (attributeValue != null ? 1 : 0)
 2357  
                 + (serverSideScript != null ? 1 : 0) <= 1)
 2358  
         {
 2359  0
             if (cbl == null || cbl.size() == 0)
 2360  
             {
 2361  0
                 if (attributeValue != null)
 2362  
                 {
 2363  0
                     return renderHTMLStringAttribute(writer, componentProperty,
 2364  
                             htmlAttrName, attributeValue);
 2365  
                 }
 2366  
                 else
 2367  
                 {
 2368  0
                     return renderHTMLStringAttribute(writer, componentProperty,
 2369  
                             htmlAttrName, serverSideScript);
 2370  
                 }
 2371  
             }
 2372  
             else
 2373  
             {
 2374  0
                 return renderHTMLStringAttribute(
 2375  
                         writer, componentProperty, htmlAttrName,
 2376  
                         cbl.get(0).getScript(
 2377  
                                 ClientBehaviorContext
 2378  
                                         .createClientBehaviorContext(
 2379  
                                                 facesContext, component,
 2380  
                                                 eventName, sourceId,
 2381  
                                                 eventParameters)));
 2382  
             }
 2383  
         }
 2384  
         else
 2385  
         {
 2386  0
             return renderHTMLStringAttribute(writer, componentProperty, htmlAttrName,
 2387  
                     HtmlRendererUtils.buildBehaviorChain(facesContext,
 2388  
                             component, sourceId, eventName,
 2389  
                             eventParameters, clientBehaviors, attributeValue,
 2390  
                             serverSideScript));
 2391  
         }
 2392  
     }
 2393  
 
 2394  
     public static boolean renderBehaviorizedAttribute(
 2395  
             FacesContext facesContext, ResponseWriter writer,
 2396  
             String componentProperty, UIComponent component, String eventName,
 2397  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2398  
             String eventName2,
 2399  
             Collection<ClientBehaviorContext.Parameter> eventParameters2,
 2400  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2401  
             String htmlAttrName, String attributeValue, String serverSideScript)
 2402  
             throws IOException
 2403  
     {
 2404  0
         return renderBehaviorizedAttribute(facesContext, writer,
 2405  
                 componentProperty, component,
 2406  
                 null, eventName,
 2407  
                 eventParameters, eventName2, eventParameters2, clientBehaviors,
 2408  
                 htmlAttrName, attributeValue, serverSideScript);
 2409  
     }
 2410  
 
 2411  
     public static boolean renderBehaviorizedAttribute(
 2412  
             FacesContext facesContext, ResponseWriter writer,
 2413  
             String componentProperty, UIComponent component,
 2414  
             String sourceId, String eventName,
 2415  
             Collection<ClientBehaviorContext.Parameter> eventParameters,
 2416  
             String eventName2,
 2417  
             Collection<ClientBehaviorContext.Parameter> eventParameters2,
 2418  
             Map<String, List<ClientBehavior>> clientBehaviors,
 2419  
             String htmlAttrName, String attributeValue, String serverSideScript)
 2420  
             throws IOException
 2421  
     {
 2422  0
         List<ClientBehavior> cb1 = (clientBehaviors != null) ? clientBehaviors
 2423  
                 .get(eventName) : null;
 2424  0
         List<ClientBehavior> cb2 = (clientBehaviors != null) ? clientBehaviors
 2425  
                 .get(eventName2) : null;
 2426  0
         if (((cb1 != null) ? cb1.size() : 0) + ((cb2 != null) ? cb2.size() : 0)
 2427  
                 + (attributeValue != null ? 1 : 0) <= 1)
 2428  
         {
 2429  0
             if (attributeValue != null)
 2430  
             {
 2431  0
                 return renderHTMLStringAttribute(writer, componentProperty,
 2432  
                         htmlAttrName, attributeValue);
 2433  
             }
 2434  0
             else if (serverSideScript != null)
 2435  
             {
 2436  0
                 return renderHTMLStringAttribute(writer, componentProperty,
 2437  
                         htmlAttrName, serverSideScript);
 2438  
             }
 2439  0
             else if (((cb1 != null) ? cb1.size() : 0) > 0)
 2440  
             {
 2441  0
                 return renderHTMLStringAttribute(
 2442  
                         writer, componentProperty, htmlAttrName,
 2443  
                         cb1.get(0).getScript(ClientBehaviorContext
 2444  
                                         .createClientBehaviorContext(
 2445  
                                                 facesContext, component,
 2446  
                                                 eventName, sourceId,
 2447  
                                                 eventParameters)));
 2448  
             }
 2449  
             else
 2450  
             {
 2451  0
                 return renderHTMLStringAttribute(
 2452  
                         writer, componentProperty, htmlAttrName,
 2453  
                         cb2.get(0).getScript(ClientBehaviorContext
 2454  
                                         .createClientBehaviorContext(
 2455  
                                                 facesContext, component,
 2456  
                                                 eventName2, sourceId,
 2457  
                                                 eventParameters2)));
 2458  
             }
 2459  
         }
 2460  
         else
 2461  
         {
 2462  0
             return renderHTMLStringAttribute(writer, componentProperty, htmlAttrName,
 2463  
                     HtmlRendererUtils.buildBehaviorChain(facesContext,
 2464  
                             component, sourceId, eventName,
 2465  
                             eventParameters, eventName2, eventParameters2,
 2466  
                             clientBehaviors, attributeValue, serverSideScript));
 2467  
         }
 2468  
     }
 2469  
     // CHECKSTYLE: ON
 2470  
     
 2471  
     /**
 2472  
      * @since 4.0.0
 2473  
      */
 2474  
     public static void renderBehaviorizedEventHandlers(
 2475  
             FacesContext facesContext, ResponseWriter writer,
 2476  
             UIComponent uiComponent,
 2477  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2478  
             throws IOException
 2479  
     {
 2480  0
         renderBehaviorizedEventHandlers(facesContext, writer, uiComponent,
 2481  
                 null, clientBehaviors);
 2482  0
     }
 2483  
 
 2484  
     public static void renderBehaviorizedEventHandlers(
 2485  
             FacesContext facesContext, ResponseWriter writer,
 2486  
             UIComponent uiComponent, String sourceId,
 2487  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2488  
             throws IOException
 2489  
     {
 2490  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONCLICK_ATTR,
 2491  
                 uiComponent, sourceId, ClientBehaviorEvents.CLICK,
 2492  
                 clientBehaviors, HTML.ONCLICK_ATTR);
 2493  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONDBLCLICK_ATTR,
 2494  
                 uiComponent, sourceId, ClientBehaviorEvents.DBLCLICK,
 2495  
                 clientBehaviors, HTML.ONDBLCLICK_ATTR);
 2496  0
         renderBehaviorizedAttribute(facesContext, writer,
 2497  
                 HTML.ONMOUSEDOWN_ATTR, uiComponent, sourceId,
 2498  
                 ClientBehaviorEvents.MOUSEDOWN, clientBehaviors,
 2499  
                 HTML.ONMOUSEDOWN_ATTR);
 2500  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEUP_ATTR,
 2501  
                 uiComponent, sourceId, ClientBehaviorEvents.MOUSEUP,
 2502  
                 clientBehaviors, HTML.ONMOUSEUP_ATTR);
 2503  0
         renderBehaviorizedAttribute(facesContext, writer,
 2504  
                 HTML.ONMOUSEOVER_ATTR, uiComponent, sourceId,
 2505  
                 ClientBehaviorEvents.MOUSEOVER, clientBehaviors,
 2506  
                 HTML.ONMOUSEOVER_ATTR);
 2507  0
         renderBehaviorizedAttribute(facesContext, writer,
 2508  
                 HTML.ONMOUSEMOVE_ATTR, uiComponent, sourceId,
 2509  
                 ClientBehaviorEvents.MOUSEMOVE, clientBehaviors,
 2510  
                 HTML.ONMOUSEMOVE_ATTR);
 2511  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEOUT_ATTR,
 2512  
                 uiComponent, sourceId, ClientBehaviorEvents.MOUSEOUT,
 2513  
                 clientBehaviors, HTML.ONMOUSEOUT_ATTR);
 2514  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYPRESS_ATTR,
 2515  
                 uiComponent, sourceId, ClientBehaviorEvents.KEYPRESS,
 2516  
                 clientBehaviors, HTML.ONKEYPRESS_ATTR);
 2517  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYDOWN_ATTR,
 2518  
                 uiComponent, sourceId, ClientBehaviorEvents.KEYDOWN,
 2519  
                 clientBehaviors, HTML.ONKEYDOWN_ATTR);
 2520  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYUP_ATTR,
 2521  
                 uiComponent, sourceId, ClientBehaviorEvents.KEYUP,
 2522  
                 clientBehaviors, HTML.ONKEYUP_ATTR);
 2523  0
     }
 2524  
 
 2525  
     /**
 2526  
      * @since 4.0.0
 2527  
      */
 2528  
     public static void renderBehaviorizedEventHandlersWithoutOnclick(
 2529  
             FacesContext facesContext, ResponseWriter writer,
 2530  
             UIComponent uiComponent,
 2531  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2532  
             throws IOException
 2533  
     {
 2534  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONDBLCLICK_ATTR,
 2535  
                 uiComponent, ClientBehaviorEvents.DBLCLICK, clientBehaviors,
 2536  
                 HTML.ONDBLCLICK_ATTR);
 2537  0
         renderBehaviorizedAttribute(facesContext, writer,
 2538  
                 HTML.ONMOUSEDOWN_ATTR, uiComponent,
 2539  
                 ClientBehaviorEvents.MOUSEDOWN, clientBehaviors,
 2540  
                 HTML.ONMOUSEDOWN_ATTR);
 2541  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEUP_ATTR,
 2542  
                 uiComponent, ClientBehaviorEvents.MOUSEUP, clientBehaviors,
 2543  
                 HTML.ONMOUSEUP_ATTR);
 2544  0
         renderBehaviorizedAttribute(facesContext, writer,
 2545  
                 HTML.ONMOUSEOVER_ATTR, uiComponent,
 2546  
                 ClientBehaviorEvents.MOUSEOVER, clientBehaviors,
 2547  
                 HTML.ONMOUSEOVER_ATTR);
 2548  0
         renderBehaviorizedAttribute(facesContext, writer,
 2549  
                 HTML.ONMOUSEMOVE_ATTR, uiComponent,
 2550  
                 ClientBehaviorEvents.MOUSEMOVE, clientBehaviors,
 2551  
                 HTML.ONMOUSEMOVE_ATTR);
 2552  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEOUT_ATTR,
 2553  
                 uiComponent, ClientBehaviorEvents.MOUSEOUT, clientBehaviors,
 2554  
                 HTML.ONMOUSEOUT_ATTR);
 2555  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYPRESS_ATTR,
 2556  
                 uiComponent, ClientBehaviorEvents.KEYPRESS, clientBehaviors,
 2557  
                 HTML.ONKEYPRESS_ATTR);
 2558  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYDOWN_ATTR,
 2559  
                 uiComponent, ClientBehaviorEvents.KEYDOWN, clientBehaviors,
 2560  
                 HTML.ONKEYDOWN_ATTR);
 2561  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYUP_ATTR,
 2562  
                 uiComponent, ClientBehaviorEvents.KEYUP, clientBehaviors,
 2563  
                 HTML.ONKEYUP_ATTR);
 2564  0
     }
 2565  
 
 2566  
     public static void renderBehaviorizedEventHandlersWithoutOnmouseoverAndOnmouseout(
 2567  
             FacesContext facesContext, ResponseWriter writer,
 2568  
             UIComponent uiComponent,
 2569  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2570  
             throws IOException
 2571  
     {
 2572  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONCLICK_ATTR,
 2573  
                 uiComponent, ClientBehaviorEvents.CLICK, clientBehaviors,
 2574  
                 HTML.ONCLICK_ATTR);
 2575  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONDBLCLICK_ATTR,
 2576  
                 uiComponent, ClientBehaviorEvents.DBLCLICK, clientBehaviors,
 2577  
                 HTML.ONDBLCLICK_ATTR);
 2578  0
         renderBehaviorizedAttribute(facesContext, writer,
 2579  
                 HTML.ONMOUSEDOWN_ATTR, uiComponent,
 2580  
                 ClientBehaviorEvents.MOUSEDOWN, clientBehaviors,
 2581  
                 HTML.ONMOUSEDOWN_ATTR);
 2582  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONMOUSEUP_ATTR,
 2583  
                 uiComponent, ClientBehaviorEvents.MOUSEUP, clientBehaviors,
 2584  
                 HTML.ONMOUSEUP_ATTR);
 2585  0
         renderBehaviorizedAttribute(facesContext, writer,
 2586  
                 HTML.ONMOUSEMOVE_ATTR, uiComponent,
 2587  
                 ClientBehaviorEvents.MOUSEMOVE, clientBehaviors,
 2588  
                 HTML.ONMOUSEMOVE_ATTR);
 2589  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYPRESS_ATTR,
 2590  
                 uiComponent, ClientBehaviorEvents.KEYPRESS, clientBehaviors,
 2591  
                 HTML.ONKEYPRESS_ATTR);
 2592  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYDOWN_ATTR,
 2593  
                 uiComponent, ClientBehaviorEvents.KEYDOWN, clientBehaviors,
 2594  
                 HTML.ONKEYDOWN_ATTR);
 2595  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONKEYUP_ATTR,
 2596  
                 uiComponent, ClientBehaviorEvents.KEYUP, clientBehaviors,
 2597  
                 HTML.ONKEYUP_ATTR);
 2598  0
     }
 2599  
 
 2600  
     /**
 2601  
      * @since 4.0.0
 2602  
      */
 2603  
     public static void renderBehaviorizedFieldEventHandlers(
 2604  
             FacesContext facesContext, ResponseWriter writer,
 2605  
             UIComponent uiComponent,
 2606  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2607  
             throws IOException
 2608  
     {
 2609  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR,
 2610  
                 uiComponent, ClientBehaviorEvents.FOCUS, clientBehaviors, HTML.ONFOCUS_ATTR);
 2611  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR,
 2612  
                 uiComponent, ClientBehaviorEvents.BLUR, clientBehaviors, HTML.ONBLUR_ATTR);
 2613  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONCHANGE_ATTR,
 2614  
                 uiComponent, ClientBehaviorEvents.CHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2615  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONSELECT_ATTR,
 2616  
                 uiComponent, ClientBehaviorEvents.SELECT, clientBehaviors, HTML.ONSELECT_ATTR);
 2617  0
     }
 2618  
 
 2619  
     public static void renderBehaviorizedFieldEventHandlersWithoutOnfocus(
 2620  
             FacesContext facesContext, ResponseWriter writer,
 2621  
             UIComponent uiComponent,
 2622  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2623  
             throws IOException
 2624  
     {
 2625  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR,
 2626  
                 uiComponent, ClientBehaviorEvents.BLUR, clientBehaviors, HTML.ONBLUR_ATTR);
 2627  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONCHANGE_ATTR,
 2628  
                 uiComponent, ClientBehaviorEvents.CHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2629  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONSELECT_ATTR,
 2630  
                 uiComponent, ClientBehaviorEvents.SELECT, clientBehaviors, HTML.ONSELECT_ATTR);
 2631  0
     }
 2632  
 
 2633  
     /**
 2634  
      * @since 4.0.0
 2635  
      */
 2636  
     public static void renderBehaviorizedFieldEventHandlersWithoutOnchange(
 2637  
             FacesContext facesContext, ResponseWriter writer,
 2638  
             UIComponent uiComponent,
 2639  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2640  
             throws IOException
 2641  
     {
 2642  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR,
 2643  
                 uiComponent, ClientBehaviorEvents.FOCUS, clientBehaviors, HTML.ONFOCUS_ATTR);
 2644  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR,
 2645  
                 uiComponent, ClientBehaviorEvents.BLUR, clientBehaviors, HTML.ONBLUR_ATTR);
 2646  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONSELECT_ATTR,
 2647  
                 uiComponent, ClientBehaviorEvents.SELECT, clientBehaviors, HTML.ONSELECT_ATTR);
 2648  0
     }
 2649  
 
 2650  
     public static void renderBehaviorizedFieldEventHandlersWithoutOnchange(
 2651  
             FacesContext facesContext, ResponseWriter writer,
 2652  
             UIComponent uiComponent, String sourceId,
 2653  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2654  
             throws IOException
 2655  
     {
 2656  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR,
 2657  
                 uiComponent, sourceId, ClientBehaviorEvents.FOCUS, clientBehaviors, HTML.ONFOCUS_ATTR);
 2658  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR,
 2659  
                 uiComponent, sourceId, ClientBehaviorEvents.BLUR, clientBehaviors, HTML.ONBLUR_ATTR);
 2660  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONSELECT_ATTR,
 2661  
                 uiComponent, sourceId, ClientBehaviorEvents.SELECT, clientBehaviors, HTML.ONSELECT_ATTR);
 2662  0
     }
 2663  
 
 2664  
     public static void renderBehaviorizedFieldEventHandlersWithoutOnchangeAndOnselect(
 2665  
             FacesContext facesContext, ResponseWriter writer,
 2666  
             UIComponent uiComponent,
 2667  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2668  
             throws IOException
 2669  
     {
 2670  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONFOCUS_ATTR,
 2671  
                 uiComponent, ClientBehaviorEvents.FOCUS, clientBehaviors, HTML.ONFOCUS_ATTR);
 2672  0
         renderBehaviorizedAttribute(facesContext, writer, HTML.ONBLUR_ATTR,
 2673  
                 uiComponent, ClientBehaviorEvents.BLUR, clientBehaviors, HTML.ONBLUR_ATTR);
 2674  0
     }
 2675  
 
 2676  
     /**
 2677  
      * @since 4.0.0
 2678  
      */
 2679  
     public static boolean renderBehaviorizedOnchangeEventHandler(
 2680  
             FacesContext facesContext, ResponseWriter writer,
 2681  
             UIComponent uiComponent,
 2682  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2683  
             throws IOException
 2684  
     {
 2685  0
         boolean hasChange = HtmlRendererUtils.hasClientBehavior(
 2686  
                 ClientBehaviorEvents.CHANGE, clientBehaviors, facesContext);
 2687  0
         boolean hasValueChange = HtmlRendererUtils
 2688  
                 .hasClientBehavior(ClientBehaviorEvents.VALUECHANGE,
 2689  
                         clientBehaviors, facesContext);
 2690  
 
 2691  0
         if (hasChange && hasValueChange)
 2692  
         {
 2693  0
             String chain = HtmlRendererUtils.buildBehaviorChain(facesContext,
 2694  
                     uiComponent, ClientBehaviorEvents.CHANGE, null,
 2695  
                     ClientBehaviorEvents.VALUECHANGE, null, clientBehaviors,
 2696  
                     (String) uiComponent.getAttributes().get(HTML.ONCHANGE_ATTR), null);
 2697  
 
 2698  0
             return HtmlRendererUtils.renderHTMLStringAttribute(writer,
 2699  
                     HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR, chain);
 2700  
         }
 2701  0
         else if (hasChange)
 2702  
         {
 2703  0
             return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext,
 2704  
                     writer, HTML.ONCHANGE_ATTR, uiComponent,
 2705  
                     ClientBehaviorEvents.CHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2706  
         }
 2707  0
         else if (hasValueChange)
 2708  
         {
 2709  0
             return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext,
 2710  
                     writer, HTML.ONCHANGE_ATTR, uiComponent,
 2711  
                     ClientBehaviorEvents.VALUECHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2712  
         }
 2713  
         else
 2714  
         {
 2715  0
             return HtmlRendererUtils.renderHTMLStringAttribute(writer, uiComponent,
 2716  
                     HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);
 2717  
         }
 2718  
     }
 2719  
 
 2720  
     public static boolean renderBehaviorizedOnchangeEventHandler(
 2721  
             FacesContext facesContext, ResponseWriter writer,
 2722  
             UIComponent uiComponent, String sourceId,
 2723  
             Map<String, List<ClientBehavior>> clientBehaviors)
 2724  
             throws IOException
 2725  
     {
 2726  0
         boolean hasChange = HtmlRendererUtils.hasClientBehavior(
 2727  
                 ClientBehaviorEvents.CHANGE, clientBehaviors, facesContext);
 2728  0
         boolean hasValueChange = HtmlRendererUtils
 2729  
                 .hasClientBehavior(ClientBehaviorEvents.VALUECHANGE,
 2730  
                         clientBehaviors, facesContext);
 2731  
 
 2732  0
         if (hasChange && hasValueChange)
 2733  
         {
 2734  0
             String chain = HtmlRendererUtils.buildBehaviorChain(facesContext,
 2735  
                     uiComponent, sourceId, ClientBehaviorEvents.CHANGE,
 2736  
                     null, ClientBehaviorEvents.VALUECHANGE, null,
 2737  
                     clientBehaviors,
 2738  
                     (String) uiComponent.getAttributes().get(HTML.ONCHANGE_ATTR), null);
 2739  
 
 2740  0
             return HtmlRendererUtils.renderHTMLStringAttribute(writer,
 2741  
                     HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR, chain);
 2742  
         }
 2743  0
         else if (hasChange)
 2744  
         {
 2745  0
             return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext,
 2746  
                     writer, HTML.ONCHANGE_ATTR, uiComponent, sourceId,
 2747  
                     ClientBehaviorEvents.CHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2748  
         }
 2749  0
         else if (hasValueChange)
 2750  
         {
 2751  0
             return HtmlRendererUtils.renderBehaviorizedAttribute(facesContext,
 2752  
                     writer, HTML.ONCHANGE_ATTR, uiComponent, sourceId,
 2753  
                     ClientBehaviorEvents.VALUECHANGE, clientBehaviors, HTML.ONCHANGE_ATTR);
 2754  
         }
 2755  
         else
 2756  
         {
 2757  0
             return HtmlRendererUtils.renderHTMLStringAttribute(writer, uiComponent,
 2758  
                     HTML.ONCHANGE_ATTR, HTML.ONCHANGE_ATTR);
 2759  
         }
 2760  
     }
 2761  
 
 2762  
     /**
 2763  
      * Returns the value of the hideNoSelectionOption attribute of the given UIComponent
 2764  
      * @param component
 2765  
      * @return
 2766  
      */
 2767  
     public static boolean isHideNoSelectionOption(UIComponent component)
 2768  
     {
 2769  
         // check hideNoSelectionOption for literal value (String) or ValueExpression (Boolean)
 2770  0
         Object hideNoSelectionOptionAttr = component.getAttributes().get(
 2771  
                 JSFAttr.HIDE_NO_SELECTION_OPTION_ATTR);
 2772  0
         return ((hideNoSelectionOptionAttr instanceof String && "true"
 2773  
                 .equalsIgnoreCase((String) hideNoSelectionOptionAttr)) || 
 2774  
                 (hideNoSelectionOptionAttr instanceof Boolean && ((Boolean) hideNoSelectionOptionAttr)));
 2775  
     }
 2776  
 
 2777  
     /**
 2778  
      * Renders all FacesMessages which have not been rendered yet with
 2779  
      * the help of a HtmlMessages component.
 2780  
      * @param facesContext
 2781  
      */
 2782  
     public static void renderUnhandledFacesMessages(FacesContext facesContext)
 2783  
             throws IOException
 2784  
     {
 2785  
         // create and configure HtmlMessages component
 2786  0
         HtmlMessages messages = (HtmlMessages) facesContext.getApplication()
 2787  
                 .createComponent(HtmlMessages.COMPONENT_TYPE);
 2788  0
         messages.setId("javax_faces_developmentstage_messages");
 2789  0
         messages.setTitle("Project Stage[Development]: Unhandled Messages");
 2790  0
         messages.setStyle("color:orange");
 2791  0
         messages.setRedisplay(false);
 2792  
         // render the component
 2793  0
         messages.encodeAll(facesContext);
 2794  0
     }
 2795  
 
 2796  
     /**
 2797  
      * The ScriptContext offers methods and fields
 2798  
      * to help with rendering out a script and keeping a
 2799  
      * proper formatting.
 2800  
      */
 2801  
     public static class ScriptContext extends JavascriptContext
 2802  
     {
 2803  
         public ScriptContext()
 2804  
         {
 2805  18
             super();
 2806  18
         }
 2807  
         public ScriptContext(boolean prettyPrint)
 2808  
         {
 2809  0
             super(prettyPrint);
 2810  0
         }
 2811  
         public ScriptContext(StringBuilder buf, boolean prettyPrint)
 2812  
         {
 2813  0
             super(buf, prettyPrint);
 2814  0
         }
 2815  
     }
 2816  
 }