Coverage Report - org.seasar.teeda.core.render.AbstractRenderer
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractRenderer
97%
115/119
91%
42/46
2.16
 
 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.render;
 17  
 
 18  
 import java.io.IOException;
 19  
 import java.util.HashMap;
 20  
 import java.util.Iterator;
 21  
 import java.util.Map;
 22  
 import java.util.Set;
 23  
 import java.util.Map.Entry;
 24  
 
 25  
 import javax.faces.component.UIComponent;
 26  
 import javax.faces.component.UIOutput;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.context.ResponseWriter;
 29  
 import javax.faces.convert.ConverterException;
 30  
 import javax.faces.internal.IgnoreAttribute;
 31  
 import javax.faces.internal.UIComponentUtil;
 32  
 import javax.faces.render.Renderer;
 33  
 
 34  
 import org.seasar.framework.beans.BeanDesc;
 35  
 import org.seasar.framework.beans.PropertyDesc;
 36  
 import org.seasar.framework.beans.factory.BeanDescFactory;
 37  
 import org.seasar.framework.util.ArrayUtil;
 38  
 import org.seasar.framework.util.AssertionUtil;
 39  
 import org.seasar.framework.util.StringUtil;
 40  
 import org.seasar.teeda.core.JsfConstants;
 41  
 import org.seasar.teeda.core.util.LoopIterator;
 42  
 import org.seasar.teeda.core.util.RenderedComponentIterator;
 43  
 import org.seasar.teeda.core.util.RendererUtil;
 44  
 
 45  
 /**
 46  
  * @author manhole
 47  
  */
 48  
 public abstract class AbstractRenderer extends Renderer {
 49  
 
 50  
     private ComponentIdLookupStrategy idLookupStartegy;
 51  
 
 52  1172
     public AbstractRenderer() {
 53  1172
         idLookupStartegy = new DefaultComponentIdLookupStrategy();
 54  1172
     }
 55  
 
 56  
     public Object getConvertedValue(FacesContext context,
 57  
             UIComponent component, Object submittedValue)
 58  
             throws ConverterException {
 59  40
         assertNotNull(context, component);
 60  4
         return RendererUtil.getConvertedUIOutputValue(context,
 61  
                 (UIOutput) component, submittedValue);
 62  
     }
 63  
 
 64  
     protected String getIdForRender(FacesContext context, UIComponent component) {
 65  299
         return idLookupStartegy.getId(context, component);
 66  
     }
 67  
 
 68  
     protected UIComponent toNullIfNotRendered(UIComponent component) {
 69  82
         if (component != null && !component.isRendered()) {
 70  4
             return null;
 71  
         }
 72  78
         return component;
 73  
     }
 74  
 
 75  
     protected void encodeComponent(FacesContext context, UIComponent component)
 76  
             throws IOException {
 77  135
         component.encodeBegin(context);
 78  135
         if (component.getRendersChildren()) {
 79  4
             component.encodeChildren(context);
 80  
         } else {
 81  131
             encodeDescendantComponent(context, component);
 82  
         }
 83  135
         component.encodeEnd(context);
 84  135
     }
 85  
 
 86  
     protected void encodeDescendantComponent(FacesContext context,
 87  
             UIComponent component) throws IOException {
 88  182
         for (Iterator it = getRenderedChildrenIterator(component); it.hasNext();) {
 89  61
             UIComponent child = (UIComponent) it.next();
 90  61
             encodeComponent(context, child);
 91  
         }
 92  182
     }
 93  
 
 94  
     // for parameter check.
 95  
     protected void assertNotNull(FacesContext context, UIComponent component) {
 96  770
         AssertionUtil.assertNotNull("context", context);
 97  698
         AssertionUtil.assertNotNull("component", component);
 98  626
     }
 99  
 
 100  
     // for styles
 101  
     protected String[] splitByComma(String s) {
 102  23
         String[] split = StringUtil.split(s, ",");
 103  46
         for (int i = 0; i < split.length; i++) {
 104  23
             split[i] = split[i].trim();
 105  
         }
 106  23
         return split;
 107  
     }
 108  
 
 109  
     protected LoopIterator toStyleLoopIterator(String s) {
 110  22
         return new LoopIterator(splitByComma(s));
 111  
     }
 112  
 
 113  
     protected Iterator getRenderedChildrenIterator(UIComponent component) {
 114  230
         return new RenderedComponentIterator(component.getChildren());
 115  
     }
 116  
 
 117  
     protected String getLabelStyleClass(UIComponent component, boolean disabled) {
 118  138
         if (disabled) {
 119  42
             return UIComponentUtil.getStringAttribute(component,
 120  
                     JsfConstants.DISABLED_CLASS_ATTR);
 121  
         } else {
 122  96
             return UIComponentUtil.getStringAttribute(component,
 123  
                     JsfConstants.ENABLED_CLASS_ATTR);
 124  
         }
 125  
     }
 126  
 
 127  
     protected void renderRemainAttributes(final UIComponent component,
 128  
             final ResponseWriter writer, final IgnoreAttribute ignore)
 129  
             throws IOException {
 130  261
         final Map map = getAllAttributesAndProperties(component, ignore);
 131  261
         renderAttributes(map, writer);
 132  261
     }
 133  
 
 134  
     protected void renderAttributes(Map attributes, ResponseWriter writer)
 135  
             throws IOException {
 136  289
         for (final Iterator it = attributes.entrySet().iterator(); it.hasNext();) {
 137  5997
             final Map.Entry entry = (Entry) it.next();
 138  5997
             final String key = (String) entry.getKey();
 139  5997
             if (isRenderAttributeName(key)) {
 140  5995
                 RendererUtil.renderAttribute(writer, key, entry.getValue());
 141  
             }
 142  
         }
 143  289
     }
 144  
 
 145  
     protected Map getAllAttributesAndProperties(final UIComponent component,
 146  
             final IgnoreAttribute ignore) {
 147  433
         final Map map = new HashMap(64);
 148  433
         final BeanDesc beanDesc = BeanDescFactory.getBeanDesc(component
 149  
                 .getClass());
 150  433
         final Object[] attributeNames = ignore.getAttributeNames();
 151  16148
         for (int i = 0; i < beanDesc.getPropertyDescSize(); i++) {
 152  15715
             final PropertyDesc propertyDesc = beanDesc.getPropertyDesc(i);
 153  15715
             final String propertyName = propertyDesc.getPropertyName();
 154  15715
             if (ArrayUtil.contains(attributeNames, propertyName)) {
 155  8613
                 continue;
 156  
             }
 157  7102
             if (propertyDesc.isReadable()) {
 158  6462
                 final Object value = propertyDesc.getValue(component);
 159  6462
                 map.put(propertyName, value);
 160  
             }
 161  
         }
 162  433
         for (Iterator itr = component.getAttributes().entrySet().iterator(); itr
 163  497
                 .hasNext();) {
 164  64
             Map.Entry entry = (Entry) itr.next();
 165  64
             final String name = (String) entry.getKey();
 166  64
             if (!isRenderAttributeName(name)) {
 167  17
                 continue;
 168  
             }
 169  47
             if (ArrayUtil.contains(attributeNames, name)) {
 170  20
                 continue;
 171  
             }
 172  27
             map.put(name, entry.getValue());
 173  
         }
 174  433
         return map;
 175  
     }
 176  
 
 177  
     /*
 178  
      * "."を含む名称は、FWなどが内部的に使っていることが多いため、
 179  
      * Teedaとしては画面に出力しないことにする。
 180  
      */
 181  
     protected boolean isRenderAttributeName(final String key) {
 182  6071
         return -1 == key.indexOf('.');
 183  
     }
 184  
 
 185  
     public void setComponentIdLookupStrategy(
 186  
             ComponentIdLookupStrategy idLookupStartegy) {
 187  1005
         this.idLookupStartegy = idLookupStartegy;
 188  1005
     }
 189  
 
 190  
     public ComponentIdLookupStrategy getComponentIdLookupStrategy() {
 191  0
         return idLookupStartegy;
 192  
     }
 193  
 
 194  
     protected boolean containsAttributeForRender(final UIComponent component,
 195  
             final IgnoreAttribute ignore) {
 196  179
         if (RendererUtil.shouldRenderIdAttribute(component)) {
 197  8
             return true;
 198  
         }
 199  171
         final Map map = getAllAttributesAndProperties(component, ignore);
 200  171
         final Set keys = map.keySet();
 201  171
         final String[] names = new String[keys.size()];
 202  171
         keys.toArray(names);
 203  171
         if (RendererUtil.containsAttributesForRender(component, names)) {
 204  8
             return true;
 205  
         }
 206  163
         return containsAttributeForRender(component.getAttributes());
 207  
     }
 208  
 
 209  
     protected boolean containsAttributeForRender(Map attributes) {
 210  190
         for (final Iterator it = attributes.entrySet().iterator(); it.hasNext();) {
 211  10
             final Map.Entry entry = (Entry) it.next();
 212  10
             final String key = (String) entry.getKey();
 213  10
             if (isRenderAttributeName(key)) {
 214  2
                 final Object value = entry.getValue();
 215  2
                 if (RendererUtil.shouldRenderAttribute(key, value)) {
 216  2
                     return true;
 217  
                 }
 218  
             }
 219  
         }
 220  188
         return false;
 221  
     }
 222  
 
 223  
     // checkbox, radio
 224  
     protected void renderCheckedAttribute(ResponseWriter writer)
 225  
             throws IOException {
 226  6
         RendererUtil.renderAttribute(writer, JsfConstants.CHECKED_ATTR,
 227  
                 JsfConstants.CHECKED_ATTR);
 228  6
     }
 229  
 
 230  
     protected void renderDisabledAttribute(ResponseWriter writer)
 231  
             throws IOException {
 232  34
         RendererUtil.renderAttribute(writer, JsfConstants.DISABLED_ATTR,
 233  
                 JsfConstants.DISABLED_ATTR);
 234  34
     }
 235  
 
 236  
     // select/option
 237  
     protected void renderSelectedAttribute(ResponseWriter writer)
 238  
             throws IOException {
 239  13
         RendererUtil.renderAttribute(writer, JsfConstants.SELECTED_ATTR,
 240  
                 JsfConstants.SELECTED_ATTR);
 241  13
     }
 242  
 
 243  
     protected void renderJavaScriptElement(final ResponseWriter writer,
 244  
             final String scriptBody) throws IOException {
 245  4
         if (StringUtil.isBlank(scriptBody)) {
 246  0
             return;
 247  
         }
 248  4
         writer.write(JsfConstants.LINE_SP);
 249  4
         writer.startElement(JsfConstants.SCRIPT_ELEM, null);
 250  4
         writer.writeAttribute(JsfConstants.LANGUAGE_ATTR,
 251  
                 JsfConstants.JAVASCRIPT_VALUE, null);
 252  4
         writer.writeAttribute(JsfConstants.TYPE_ATTR,
 253  
                 JsfConstants.TEXT_JAVASCRIPT_VALUE, null);
 254  4
         writer.write(JsfConstants.LINE_SP);
 255  4
         writer.write("<!--");
 256  4
         writer.write(JsfConstants.LINE_SP);
 257  4
         writer.write(scriptBody);
 258  4
         writer.write(JsfConstants.LINE_SP);
 259  4
         writer.write("//-->");
 260  4
         writer.write(JsfConstants.LINE_SP);
 261  4
         writer.endElement(JsfConstants.SCRIPT_ELEM);
 262  4
     }
 263  
 
 264  
     protected void renderIncludeJavaScript(final ResponseWriter writer,
 265  
             final String path) throws IOException {
 266  1
         if (StringUtil.isBlank(path)) {
 267  0
             return;
 268  
         }
 269  1
         writer.startElement(JsfConstants.SCRIPT_ELEM, null);
 270  1
         writer.writeAttribute(JsfConstants.LANGUAGE_ATTR,
 271  
                 JsfConstants.JAVASCRIPT_VALUE, null);
 272  1
         writer.writeAttribute(JsfConstants.TYPE_ATTR,
 273  
                 JsfConstants.TEXT_JAVASCRIPT_VALUE, null);
 274  1
         writer.writeAttribute(JsfConstants.SRC_ATTR, path, null);
 275  1
         writer.endElement(JsfConstants.SCRIPT_ELEM);
 276  1
     }
 277  
 
 278  
     protected void renderStyleSheet(final ResponseWriter writer,
 279  
             final String path) throws IOException {
 280  1
         if (StringUtil.isBlank(path)) {
 281  0
             return;
 282  
         }
 283  1
         writer.startElement(JsfConstants.LINK_ELEM, null);
 284  1
         writer.writeAttribute(JsfConstants.TYPE_ATTR,
 285  
                 JsfConstants.TEXT_CSS_VALUE, null);
 286  1
         writer.writeAttribute(JsfConstants.REL_ATTR,
 287  
                 JsfConstants.STYLESHEET_VALUE, null);
 288  1
         writer.writeAttribute(JsfConstants.HREF_ATTR, path, null);
 289  1
         writer.endElement(JsfConstants.LINK_ELEM);
 290  1
     }
 291  
 }