Coverage Report - org.seasar.teeda.core.util.RendererUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
RendererUtil
86%
132/153
84%
76/90
4.619
 
 1  
 /*
 2  
  * Copyright 2004-2011 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.teeda.core.util;
 17  
 
 18  
 import java.io.IOException;
 19  
 import java.lang.reflect.Array;
 20  
 import java.util.Iterator;
 21  
 import java.util.Map;
 22  
 
 23  
 import javax.faces.FacesException;
 24  
 import javax.faces.application.FacesMessage;
 25  
 import javax.faces.component.ComponentUtil_;
 26  
 import javax.faces.component.UIComponent;
 27  
 import javax.faces.component.UIInput;
 28  
 import javax.faces.component.UIOutput;
 29  
 import javax.faces.component.UIViewRoot;
 30  
 import javax.faces.context.FacesContext;
 31  
 import javax.faces.context.ResponseWriter;
 32  
 import javax.faces.convert.Converter;
 33  
 import javax.faces.convert.ConverterException;
 34  
 import javax.faces.el.ValueBinding;
 35  
 import javax.faces.internal.ConverterResource;
 36  
 import javax.faces.internal.FacesMessageUtil;
 37  
 import javax.faces.internal.RenderKitUtil;
 38  
 import javax.faces.internal.UIComponentUtil;
 39  
 import javax.faces.internal.UIDefaultAttribute;
 40  
 import javax.faces.render.RenderKit;
 41  
 import javax.faces.render.Renderer;
 42  
 
 43  
 import org.seasar.framework.log.Logger;
 44  
 import org.seasar.framework.util.ArrayUtil;
 45  
 import org.seasar.framework.util.AssertionUtil;
 46  
 import org.seasar.framework.util.IntegerConversionUtil;
 47  
 import org.seasar.teeda.core.JsfConstants;
 48  
 
 49  
 /**
 50  
  * @author manhole
 51  
  */
 52  0
 public class RendererUtil {
 53  
 
 54  2
     private static final Logger logger = Logger.getLogger(RendererUtil.class);
 55  
 
 56  
     public static boolean containsAttributesForRender(
 57  
             final UIComponent component, final String[] attributeNames) {
 58  174
         final Map attributes = component.getAttributes();
 59  659
         for (int i = 0, len = attributeNames.length; i < len; i++) {
 60  494
             final String attributeName = attributeNames[i];
 61  
             /*
 62  
              * don't use UIComponent#containsKey method.
 63  
              *
 64  
              * because when attributeName matches a property of this
 65  
              * UIComponent, containsKey returns false. See
 66  
              * UIComponent#getAttributes API document.
 67  
              */
 68  494
             final Object value = attributes.get(attributeName);
 69  494
             if (shouldRenderAttribute(attributeName, value)) {
 70  9
                 return true;
 71  
             }
 72  
         }
 73  165
         return false;
 74  
     }
 75  
 
 76  
     public static boolean renderAttributes(final ResponseWriter writer,
 77  
             final UIComponent component, final String[] attributeNames)
 78  
             throws IOException {
 79  
 
 80  26
         boolean somethingDone = false;
 81  104
         for (int i = 0, len = attributeNames.length; i < len; i++) {
 82  78
             final String attrName = attributeNames[i];
 83  78
             if (renderAttribute(writer, component, attrName)) {
 84  6
                 somethingDone = true;
 85  
             }
 86  
         }
 87  26
         return somethingDone;
 88  
     }
 89  
 
 90  
     static boolean renderAttribute(final ResponseWriter writer,
 91  
             final UIComponent component, final String attributeName)
 92  
             throws IOException {
 93  
 
 94  78
         final Object value = component.getAttributes().get(attributeName);
 95  78
         return renderAttribute(writer, attributeName, value, attributeName);
 96  
     }
 97  
 
 98  
     public static void renderAttribute(final ResponseWriter writer,
 99  
             final String attributeName, final Object value) throws IOException {
 100  6978
         renderAttribute(writer, attributeName, value, attributeName);
 101  6978
     }
 102  
 
 103  
     public static boolean renderAttribute(final ResponseWriter writer,
 104  
             String attributeName, Object value, final String propertyName)
 105  
             throws IOException {
 106  7175
         if (!shouldRenderAttribute(attributeName, value)) {
 107  5800
             return false;
 108  
         }
 109  1375
         attributeName = toHtmlAttributeName(attributeName);
 110  1375
         value = convertValue(attributeName, value);
 111  1375
         writer.writeAttribute(attributeName, value, propertyName);
 112  1375
         return true;
 113  
     }
 114  
 
 115  
     private static Object convertValue(final String attributeName,
 116  
             final Object value) {
 117  1375
         if (JsfConstants.CHECKED_ATTR.equals(attributeName)) {
 118  6
             return JsfConstants.CHECKED_ATTR;
 119  1369
         } else if (JsfConstants.SELECTED_ATTR.equals(attributeName)) {
 120  13
             return JsfConstants.SELECTED_ATTR;
 121  1356
         } else if (JsfConstants.DISABLED_ATTR.equals(attributeName)) {
 122  49
             return JsfConstants.DISABLED_ATTR;
 123  1307
         } else if (JsfConstants.READONLY_ATTR.equals(attributeName)) {
 124  12
             return JsfConstants.READONLY_ATTR;
 125  
         }
 126  1295
         return value;
 127  
     }
 128  
 
 129  
     private static String toHtmlAttributeName(final String attributeName) {
 130  1375
         if (attributeName.equalsIgnoreCase(JsfConstants.STYLE_CLASS_ATTR)) {
 131  42
             return JsfConstants.CLASS_ATTR;
 132  1333
         } else if (attributeName
 133  
                 .equalsIgnoreCase(JsfConstants.ACCEPTCHARSET_ATTR)) {
 134  1
             return JsfConstants.ACCEPT_CHARSET_ATTR;
 135  
         } else {
 136  1332
             return attributeName;
 137  
         }
 138  
     }
 139  
 
 140  
     public static boolean shouldRenderAttribute(final String attributeName,
 141  
             final Object value) {
 142  7671
         if (isDefaultAttributeValue(value)) {
 143  6273
             return false;
 144  
         }
 145  1398
         if (JsfConstants.COLSPAN_ATTR.equals(attributeName)) {
 146  20
             final Integer integerValue = IntegerConversionUtil.toInteger(value);
 147  20
             if (integerValue == null) {
 148  0
                 return false;
 149  
             }
 150  20
             if (integerValue.intValue() <= 1) {
 151  12
                 return false;
 152  
             }
 153  
         }
 154  1386
         if (JsfConstants.ESCAPE_ATTR.equals(attributeName)) {
 155  0
             return false;
 156  
         }
 157  1386
         if (JsfConstants.ID_ATTR.equals(attributeName)) {
 158  86
             return shouldRenderIdAttribute(value.toString());
 159  
         }
 160  1300
         return true;
 161  
     }
 162  
 
 163  
     static boolean isDefaultAttributeValue(final Object value) {
 164  7680
         if (value == null) {
 165  5656
             return true;
 166  
         }
 167  2024
         if (value instanceof Boolean) {
 168  545
             return UIDefaultAttribute.isDefaultBoolean(((Boolean) value)
 169  
                     .booleanValue());
 170  
         }
 171  1479
         if (value instanceof Integer) {
 172  175
             return UIDefaultAttribute
 173  
                     .isDefaultInt(((Integer) value).intValue());
 174  
         }
 175  1304
         return false;
 176  
     }
 177  
 
 178  
     public static boolean shouldRenderIdAttribute(final UIComponent component) {
 179  477
         return shouldRenderIdAttribute(component.getId());
 180  
     }
 181  
 
 182  
     private static boolean shouldRenderIdAttribute(final String id) {
 183  563
         if ((id != null) && !id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
 184  181
             return true;
 185  
         }
 186  382
         return false;
 187  
     }
 188  
 
 189  
     public static void renderIdAttributeIfNecessary(
 190  
             final ResponseWriter writer, final UIComponent component,
 191  
             final String idValue) throws IOException {
 192  273
         if (RendererUtil.shouldRenderIdAttribute(component)) {
 193  85
             RendererUtil.renderAttribute(writer, JsfConstants.ID_ATTR, idValue);
 194  
         }
 195  273
     }
 196  
 
 197  
     public static Object getConvertedValue(final FacesContext context,
 198  
             final UIInput component, final Object submittedValue) {
 199  
         try {
 200  3
             final Renderer renderer = getRenderer(context, component);
 201  3
             if (renderer != null) {
 202  0
                 return renderer.getConvertedValue(context, component,
 203  
                         submittedValue);
 204  3
             } else if (submittedValue instanceof String) {
 205  0
                 return getConvertedUIOutputValue(context, component,
 206  
                         submittedValue);
 207  
             }
 208  0
         } catch (final ConverterException e) {
 209  0
             final FacesMessage facesMessage = e.getFacesMessage();
 210  0
             if (facesMessage != null) {
 211  0
                 context
 212  
                         .addMessage(component.getClientId(context),
 213  
                                 facesMessage);
 214  
             } else {
 215  0
                 final Object[] args = new Object[] { UIComponentUtil
 216  
                         .getLabel(component) };
 217  0
                 context.addMessage(component.getClientId(context),
 218  
                         FacesMessageUtil.getMessage(context,
 219  
                                 UIInput.CONVERSION_MESSAGE_ID, args));
 220  
             }
 221  0
             component.setValid(false);
 222  3
         }
 223  3
         return submittedValue;
 224  
     }
 225  
 
 226  
     static Renderer getRenderer(final FacesContext context,
 227  
             final UIComponent component) {
 228  3
         final String rendererType = component.getRendererType();
 229  3
         if (rendererType == null) {
 230  0
             return null;
 231  
         }
 232  3
         final RenderKit renderKit = RenderKitUtil.getRenderKit(context);
 233  3
         return renderKit.getRenderer(component.getFamily(), rendererType);
 234  
     }
 235  
 
 236  
     public static Object getConvertedUIOutputValue(final FacesContext context,
 237  
             final UIOutput output, final Object submittedValue)
 238  
             throws ConverterException {
 239  6
         if (submittedValue == null) {
 240  0
             return null;
 241  
         }
 242  6
         final Converter converter = findConverter(context, output);
 243  6
         if (converter == null) {
 244  2
             return submittedValue;
 245  
         }
 246  4
         return converter.getAsObject(context, output,
 247  
                 (submittedValue instanceof String) ? (String) submittedValue
 248  
                         : null);
 249  
     }
 250  
 
 251  
     public static Object getConvertedUIOutputValues(final FacesContext context,
 252  
             final UIOutput output, final Object submittedValue) {
 253  5
         if (submittedValue == null) {
 254  1
             return null;
 255  
         }
 256  4
         final Converter converter = findConverter(context, output);
 257  4
         if (converter == null) {
 258  1
             return submittedValue;
 259  
         }
 260  3
         final int length = Array.getLength(submittedValue);
 261  3
         final Class valueType = getValueType(context, output);
 262  3
         final Object ret = Array.newInstance(valueType, length);
 263  9
         for (int i = 0; i < length; ++i) {
 264  6
             final Object target = Array.get(submittedValue, i);
 265  6
             final String value = (target instanceof String) ? (String) target
 266  
                     : null;
 267  6
             final Object o = converter.getAsObject(context, output, value);
 268  6
             ArrayUtil.setArrayValue(ret, valueType, o, i);
 269  
         }
 270  3
         return ret;
 271  
     }
 272  
 
 273  
     public static Converter findConverter(final FacesContext context,
 274  
             final UIOutput component) {
 275  
 
 276  10
         Converter converter = component.getConverter();
 277  10
         if (converter != null) {
 278  7
             return converter;
 279  
         }
 280  3
         ValueBinding vb = component.getValueBinding("value");
 281  3
         if (vb != null) {
 282  1
             String expression = vb.getExpressionString();
 283  1
             converter = ConverterResource.getConverter(expression);
 284  1
             if (converter != null) {
 285  0
                 return converter;
 286  
             }
 287  
         }
 288  3
         final Class valueType = getValueType(context, component);
 289  3
         if (ComponentUtil_.isPerformNoConversion(valueType)) {
 290  3
             return null;
 291  
         }
 292  
         try {
 293  0
             return context.getApplication().createConverter(valueType);
 294  0
         } catch (final FacesException ex) {
 295  0
             logger.log(ex);
 296  0
             return null;
 297  
         }
 298  
     }
 299  
 
 300  
     static Class getValueType(final FacesContext context,
 301  
             final UIOutput component) {
 302  6
         final ValueBinding vb = component.getValueBinding("value");
 303  6
         if (vb == null) {
 304  2
             return null;
 305  
         }
 306  4
         final Class valueType = vb.getType(context);
 307  4
         if (valueType == null) {
 308  0
             return null;
 309  
         }
 310  4
         if (valueType.isArray()) {
 311  3
             return valueType.getComponentType();
 312  
         } else {
 313  1
             return valueType;
 314  
         }
 315  
     }
 316  
 
 317  
     public static void renderChild(FacesContext context, UIComponent child)
 318  
             throws IOException {
 319  3
         AssertionUtil.assertNotNull("context", context);
 320  3
         AssertionUtil.assertNotNull("child", child);
 321  3
         if (!child.isRendered()) {
 322  0
             return;
 323  
         }
 324  3
         child.encodeBegin(context);
 325  3
         if (child.getRendersChildren()) {
 326  2
             child.encodeChildren(context);
 327  
         } else {
 328  1
             renderChildren(context, child);
 329  
         }
 330  3
         child.encodeEnd(context);
 331  3
     }
 332  
 
 333  
     public static void renderChildren(FacesContext context,
 334  
             UIComponent component) throws IOException {
 335  2
         AssertionUtil.assertNotNull("context", context);
 336  2
         AssertionUtil.assertNotNull("child", component);
 337  2
         if (component.getChildCount() > 0) {
 338  1
             for (Iterator it = component.getChildren().iterator(); it.hasNext();) {
 339  1
                 UIComponent child = (UIComponent) it.next();
 340  1
                 renderChild(context, child);
 341  
             }
 342  
         }
 343  2
     }
 344  
 
 345  
     public static void renderHidden(UIComponent component,
 346  
             ResponseWriter writer, String name, Object value)
 347  
             throws IOException {
 348  19
         writer.startElement(JsfConstants.INPUT_ELEM, component);
 349  19
         RendererUtil.renderAttribute(writer, JsfConstants.TYPE_ATTR,
 350  
                 JsfConstants.HIDDEN_VALUE);
 351  19
         RendererUtil.renderAttribute(writer, JsfConstants.NAME_ATTR, name);
 352  19
         RendererUtil.renderAttribute(writer, JsfConstants.VALUE_ATTR, value);
 353  19
         writer.endElement(JsfConstants.INPUT_ELEM);
 354  19
     }
 355  
 }