Coverage Report - javax.faces.component._ComponentUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
_ComponentUtils
43%
75/173
35%
40/112
7.462
 
 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 javax.faces.component;
 20  
 
 21  
 import javax.el.ValueExpression;
 22  
 import javax.faces.application.FacesMessage;
 23  
 import javax.faces.context.FacesContext;
 24  
 import javax.faces.el.EvaluationException;
 25  
 import javax.faces.el.MethodBinding;
 26  
 import javax.faces.el.ValueBinding;
 27  
 import javax.faces.validator.Validator;
 28  
 import javax.faces.validator.ValidatorException;
 29  
 import java.util.Collection;
 30  
 
 31  
 /**
 32  
  * A collection of static helper methods for locating UIComponents.
 33  
  */
 34  
 class _ComponentUtils
 35  
 {
 36  
     public static final String V_ID_PREFIX = "__v_";
 37  
     public static final String RD_ID_PREFIX = "__rd_";
 38  
     public static final int UNIQUE_COMPONENT_V_IDS_SIZE = 50;
 39  
     public static final int UNIQUE_COMPONENT_RD_IDS_SIZE = 50;
 40  
     public static final String[] UNIQUE_COMPONENT_V_IDS;
 41  
     public static final String[] UNIQUE_COMPONENT_RD_IDS;
 42  
     
 43  
     static 
 44  
     {
 45  2
         String[] uniqueV = new String[UNIQUE_COMPONENT_V_IDS_SIZE];
 46  2
         String[] uniqueRD = new String[UNIQUE_COMPONENT_RD_IDS_SIZE];
 47  2
         StringBuilder bld = new StringBuilder(20);
 48  102
         for (int i = 0; i < UNIQUE_COMPONENT_V_IDS_SIZE; i++)
 49  
         {
 50  100
             uniqueV[i] = bld.append(UIViewRoot.UNIQUE_ID_PREFIX).append("__v_").append(i).toString();
 51  100
             bld.setLength(0);
 52  
         }
 53  102
         for (int i = 0; i < UNIQUE_COMPONENT_RD_IDS_SIZE; i++)
 54  
         {
 55  100
             uniqueRD[i] = bld.append(UIViewRoot.UNIQUE_ID_PREFIX).append("__rd_").append(i).toString();
 56  100
             bld.setLength(0);
 57  
         }
 58  2
         UNIQUE_COMPONENT_RD_IDS = uniqueRD;
 59  2
         UNIQUE_COMPONENT_V_IDS = uniqueV;
 60  2
     }
 61  
     
 62  
     private _ComponentUtils()
 63  0
     {
 64  0
     }
 65  
 
 66  
     static UIComponent findParentNamingContainer(UIComponent component, boolean returnRootIfNotFound)
 67  
     {
 68  316
         UIComponent parent = component.getParent();
 69  316
         if (returnRootIfNotFound && parent == null)
 70  
         {
 71  2
             return component;
 72  
         }
 73  486
         while (parent != null)
 74  
         {
 75  346
             if (parent instanceof NamingContainer)
 76  
             {
 77  174
                 return parent;
 78  
             }
 79  172
             if (returnRootIfNotFound)
 80  
             {
 81  2
                 UIComponent nextParent = parent.getParent();
 82  2
                 if (nextParent == null)
 83  
                 {
 84  0
                     return parent; // Root
 85  
                 }
 86  2
                 parent = nextParent;
 87  2
             }
 88  
             else
 89  
             {
 90  170
                 parent = parent.getParent();
 91  
             }
 92  
         }
 93  140
         return null;
 94  
     }
 95  
 
 96  
     static UniqueIdVendor findParentUniqueIdVendor(UIComponent component)
 97  
     {
 98  46
         UIComponent parent = component.getParent();
 99  
 
 100  48
         while (parent != null)
 101  
         {
 102  6
             if (parent instanceof UniqueIdVendor)
 103  
             {
 104  4
                 return (UniqueIdVendor) parent;
 105  
             }
 106  2
             parent = parent.getParent();
 107  
         }
 108  42
         return null;
 109  
     }
 110  
     
 111  
     static UIComponent getRootComponent(UIComponent component)
 112  
     {
 113  
         UIComponent parent;
 114  
         for (;;)
 115  
         {
 116  24
             parent = component.getParent();
 117  24
             if (parent == null)
 118  
             {
 119  20
                 return component;
 120  
             }
 121  4
             component = parent;
 122  
         }
 123  
     }
 124  
 
 125  
     /**
 126  
      * Find the component with the specified id starting from the specified component.
 127  
      * <p>
 128  
      * Param id must not contain any NamingContainer.SEPARATOR_CHAR characters (ie ":"). This method explicitly does
 129  
      * <i>not</i> search into any child naming container components; this is expected to be handled by the caller of
 130  
      * this method.
 131  
      * <p>
 132  
      * For an implementation of findComponent which does descend into child naming components, see
 133  
      * org.apache.myfaces.custom.util.ComponentUtils.
 134  
      * 
 135  
      * @return findBase, a descendant of findBase, or null.
 136  
      */
 137  
     static UIComponent findComponent(UIComponent findBase, String id, final char separatorChar)
 138  
     {
 139  74
         if (!(findBase instanceof NamingContainer) && idsAreEqual(id, findBase))
 140  
         {
 141  20
             return findBase;
 142  
         }
 143  
 
 144  54
         int facetCount = findBase.getFacetCount();
 145  54
         if (facetCount > 0)
 146  
         {
 147  0
             for (UIComponent facet : findBase.getFacets().values())
 148  
             {
 149  0
                 if (!(facet instanceof NamingContainer))
 150  
                 {
 151  0
                     UIComponent find = findComponent(facet, id, separatorChar);
 152  0
                     if (find != null)
 153  
                     {
 154  0
                         return find;
 155  
                     }
 156  0
                 }
 157  0
                 else if (idsAreEqual(id, facet))
 158  
                 {
 159  0
                     return facet;
 160  
                 }
 161  0
             }
 162  
         }
 163  
         
 164  58
         for (int i = 0, childCount = findBase.getChildCount(); i < childCount; i++)
 165  
         {
 166  54
             UIComponent child = findBase.getChildren().get(i);
 167  54
             if (!(child instanceof NamingContainer))
 168  
             {
 169  32
                 UIComponent find = findComponent(child, id, separatorChar);
 170  32
                 if (find != null)
 171  
                 {
 172  32
                     return find;
 173  
                 }
 174  0
             }
 175  22
             else if (idsAreEqual(id, child))
 176  
             {
 177  18
                 return child;
 178  
             }
 179  
         }
 180  
 
 181  4
         if (findBase instanceof NamingContainer && idsAreEqual(id, findBase))
 182  
         {
 183  0
             return findBase;
 184  
         }
 185  
 
 186  4
         return null;
 187  
     }
 188  
     
 189  
     static UIComponent findComponentChildOrFacetFrom(UIComponent parent, String id, String innerExpr)
 190  
     {
 191  0
         if (parent.getFacetCount() > 0)
 192  
         {
 193  0
             for (UIComponent facet : parent.getFacets().values())
 194  
             {
 195  0
                 if (id.equals(facet.getId()))
 196  
                 {
 197  0
                     if (innerExpr == null)
 198  
                     {
 199  0
                         return facet;
 200  
                     }
 201  0
                     else if (facet instanceof NamingContainer)
 202  
                     {
 203  0
                         UIComponent find = facet.findComponent(innerExpr);
 204  0
                         if (find != null)
 205  
                         {
 206  0
                             return find;
 207  
                         }
 208  0
                     }
 209  
                 }
 210  0
                 else if (!(facet instanceof NamingContainer))
 211  
                 {
 212  0
                     UIComponent find = findComponentChildOrFacetFrom(facet, id, innerExpr);
 213  0
                     if (find != null)
 214  
                     {
 215  0
                         return find;
 216  
                     }
 217  
                 }
 218  0
             }
 219  
         }
 220  0
         if (parent.getChildCount() > 0)
 221  
         {
 222  0
             for (int i = 0, childCount = parent.getChildCount(); i < childCount; i++)
 223  
             {
 224  0
                 UIComponent child = parent.getChildren().get(i);
 225  0
                 if (id.equals(child.getId()))
 226  
                 {
 227  0
                     if (innerExpr == null)
 228  
                     {
 229  0
                         return child;
 230  
                     }
 231  0
                     else if (child instanceof NamingContainer)
 232  
                     {
 233  0
                         UIComponent find = child.findComponent(innerExpr);
 234  0
                         if (find != null)
 235  
                         {
 236  0
                             return find;
 237  
                         }
 238  0
                     }
 239  
                 }
 240  0
                 else if (!(child instanceof NamingContainer))
 241  
                 {
 242  0
                     UIComponent find = findComponentChildOrFacetFrom(child, id, innerExpr);
 243  0
                     if (find != null)
 244  
                     {
 245  0
                         return find;
 246  
                     }
 247  
                 }
 248  
             }
 249  
         }
 250  0
         return null;
 251  
     }
 252  
 
 253  
     /*
 254  
      * Return true if the specified component matches the provided id. This needs some quirks to handle components whose
 255  
      * id value gets dynamically "tweaked", eg a UIData component whose id gets the current row index appended to it.
 256  
      */
 257  
     private static boolean idsAreEqual(String id, UIComponent cmp)
 258  
     {
 259  76
         if (id.equals(cmp.getId()))
 260  
         {
 261  38
             return true;
 262  
         }
 263  
 
 264  38
         return false;
 265  
     }
 266  
 
 267  
     static void callValidators(FacesContext context, UIInput input, Object convertedValue)
 268  
     {
 269  
         // first invoke the list of validator components
 270  30
         Validator[] validators = input.getValidators();
 271  38
         for (int i = 0; i < validators.length; i++)
 272  
         {
 273  10
             Validator validator = validators[i];
 274  
             try
 275  
             {
 276  10
                 validator.validate(context, input, convertedValue);
 277  
             }
 278  4
             catch (ValidatorException e)
 279  
             {
 280  4
                 input.setValid(false);
 281  
 
 282  4
                 String validatorMessage = input.getValidatorMessage();
 283  4
                 if (validatorMessage != null)
 284  
                 {
 285  2
                     context.addMessage(input.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR,
 286  
                         validatorMessage, validatorMessage));
 287  
                 }
 288  
                 else
 289  
                 {
 290  2
                     FacesMessage facesMessage = e.getFacesMessage();
 291  2
                     if (facesMessage != null)
 292  
                     {
 293  2
                         context.addMessage(input.getClientId(context), facesMessage);
 294  
                     }
 295  2
                     Collection<FacesMessage> facesMessages = e.getFacesMessages();
 296  2
                     if (facesMessages != null)
 297  
                     {
 298  0
                         for (FacesMessage message : facesMessages)
 299  
                         {
 300  0
                             context.addMessage(input.getClientId(context), message);
 301  0
                         }
 302  
                     }
 303  
                 }
 304  4
             }
 305  
         }
 306  
 
 307  
         // now invoke the validator method defined as a method-binding attribute
 308  
         // on the component
 309  28
         MethodBinding validatorBinding = input.getValidator();
 310  28
         if (validatorBinding != null)
 311  
         {
 312  
             try
 313  
             {
 314  4
                 validatorBinding.invoke(context, new Object[] { context, input, convertedValue });
 315  
             }
 316  0
             catch (EvaluationException e)
 317  
             {
 318  0
                 input.setValid(false);
 319  0
                 Throwable cause = e.getCause();
 320  0
                 if (cause instanceof ValidatorException)
 321  
                 {
 322  0
                     String validatorMessage = input.getValidatorMessage();
 323  0
                     if (validatorMessage != null)
 324  
                     {
 325  0
                         context.addMessage(input.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR,
 326  
                             validatorMessage, validatorMessage));
 327  
                     }
 328  
                     else
 329  
                     {
 330  0
                         FacesMessage facesMessage = ((ValidatorException)cause).getFacesMessage();
 331  0
                         if (facesMessage != null)
 332  
                         {
 333  0
                             context.addMessage(input.getClientId(context), facesMessage);
 334  
                         }
 335  0
                         Collection<FacesMessage> facesMessages = ((ValidatorException)cause).getFacesMessages();
 336  0
                         if (facesMessages != null)
 337  
                         {
 338  0
                             for (FacesMessage message : facesMessages)
 339  
                             {
 340  0
                                 context.addMessage(input.getClientId(context), message);
 341  0
                             }
 342  
                         }
 343  
                     }
 344  0
                 }
 345  
                 else
 346  
                 {
 347  0
                     throw e;
 348  
                 }
 349  4
             }
 350  
         }
 351  28
     }
 352  
 
 353  
     static String getStringValue(FacesContext context, ValueBinding vb)
 354  
     {
 355  0
         Object value = vb.getValue(context);
 356  0
         if (value == null)
 357  
         {
 358  0
             return null;
 359  
         }
 360  0
         return value.toString();
 361  
     }
 362  
 
 363  
     @SuppressWarnings("unchecked")
 364  
     static <T> T getExpressionValue(UIComponent component, String attribute, T overrideValue, T defaultValue)
 365  
     {
 366  0
         if (overrideValue != null)
 367  
         {
 368  0
             return overrideValue;
 369  
         }
 370  0
         ValueExpression ve = component.getValueExpression(attribute);
 371  0
         if (ve != null)
 372  
         {
 373  0
             return (T)ve.getValue(component.getFacesContext().getELContext());
 374  
         }
 375  0
         return defaultValue;
 376  
     }
 377  
 
 378  
     static String getPathToComponent(UIComponent component)
 379  
     {
 380  0
         StringBuffer buf = new StringBuffer();
 381  
 
 382  0
         if (component == null)
 383  
         {
 384  0
             buf.append("{Component-Path : ");
 385  0
             buf.append("[null]}");
 386  0
             return buf.toString();
 387  
         }
 388  
 
 389  0
         getPathToComponent(component, buf);
 390  
 
 391  0
         buf.insert(0, "{Component-Path : ");
 392  0
         buf.append("}");
 393  
 
 394  0
         return buf.toString();
 395  
     }
 396  
     
 397  
     /**
 398  
      * Call {@link UIComponent#pushComponentToEL(javax.faces.context.FacesContext,javax.faces.component.UIComponent)},
 399  
      * reads the isRendered property, call {@link
 400  
      * UIComponent#popComponentFromEL} and returns the value of isRendered.
 401  
      */
 402  
     static boolean isRendered(FacesContext facesContext, UIComponent uiComponent)
 403  
     {
 404  
         // We must call pushComponentToEL here because ValueExpression may have 
 405  
         // implicit object "component" used. 
 406  
         try
 407  
         {
 408  36
             uiComponent.pushComponentToEL(facesContext, uiComponent);
 409  36
             return uiComponent.isRendered();
 410  
         }
 411  
         finally
 412  
         {       
 413  36
             uiComponent.popComponentFromEL(facesContext);
 414  
         }
 415  
     }
 416  
 
 417  
     private static void getPathToComponent(UIComponent component, StringBuffer buf)
 418  
     {
 419  0
         if (component == null)
 420  
         {
 421  0
             return;
 422  
         }
 423  
 
 424  0
         StringBuffer intBuf = new StringBuffer();
 425  
 
 426  0
         intBuf.append("[Class: ");
 427  0
         intBuf.append(component.getClass().getName());
 428  0
         if (component instanceof UIViewRoot)
 429  
         {
 430  0
             intBuf.append(",ViewId: ");
 431  0
             intBuf.append(((UIViewRoot)component).getViewId());
 432  
         }
 433  
         else
 434  
         {
 435  0
             intBuf.append(",Id: ");
 436  0
             intBuf.append(component.getId());
 437  
         }
 438  0
         intBuf.append("]");
 439  
 
 440  0
         buf.insert(0, intBuf.toString());
 441  
 
 442  0
         getPathToComponent(component.getParent(), buf);
 443  0
     }
 444  
 }