Coverage Report - javax.faces.webapp.UIComponentTag
 
Classes in this File Line Coverage Branch Coverage Complexity
UIComponentTag
56%
139/247
33%
40/122
2.659
 
 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 javax.faces.webapp;
 17  
 
 18  
 import java.io.IOException;
 19  
 import java.util.ArrayList;
 20  
 import java.util.HashMap;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 
 25  
 import javax.faces.component.UIComponent;
 26  
 import javax.faces.component.UIViewRoot;
 27  
 import javax.faces.context.FacesContext;
 28  
 import javax.faces.context.ResponseWriter;
 29  
 import javax.faces.internal.InternalConstants;
 30  
 import javax.faces.internal.PageContextUtil;
 31  
 import javax.faces.internal.ValueBindingUtil;
 32  
 import javax.faces.internal.WebAppUtil;
 33  
 import javax.servlet.jsp.JspException;
 34  
 import javax.servlet.jsp.PageContext;
 35  
 import javax.servlet.jsp.tagext.Tag;
 36  
 
 37  
 import org.seasar.framework.util.AssertionUtil;
 38  
 import org.seasar.teeda.core.taglib.UIComponentTagPropertyUtil;
 39  
 
 40  
 /**
 41  
  * @author shot
 42  
  */
 43  130
 public abstract class UIComponentTag implements Tag {
 44  
 
 45  
     //TODO need to re-think for tag problem with jsp
 46  130
     private UIComponent component = null;
 47  
 
 48  130
     private FacesContext context = null;
 49  
 
 50  130
     private boolean created = false;
 51  
 
 52  130
     private List createdComponents = null;
 53  
 
 54  130
     private List createdFacets = null;
 55  
 
 56  130
     protected PageContext pageContext = null;
 57  
 
 58  130
     private Tag parent = null;
 59  
 
 60  130
     private String binding = null;
 61  
 
 62  130
     private String id = null;
 63  
 
 64  130
     private String rendered = null;
 65  
 
 66  
     public void setBinding(final String binding) throws JspException {
 67  1
         if (!isValueReference(binding)) {
 68  1
             throw new IllegalArgumentException();
 69  
         }
 70  0
         this.binding = binding;
 71  0
     }
 72  
 
 73  
     public void setId(final String id) {
 74  1
         if ((null != id) && id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX)) {
 75  1
             throw new IllegalArgumentException();
 76  
         }
 77  0
         this.id = id;
 78  0
     }
 79  
 
 80  
     public void setRendered(final String rendered) {
 81  0
         this.rendered = rendered;
 82  0
     }
 83  
 
 84  
     protected void setComponentProperty(UIComponent component,
 85  
             String propertyName, String value) {
 86  2543
         UIComponentTagPropertyUtil.setComponentProperty(component,
 87  
                 propertyName, value);
 88  2543
     }
 89  
 
 90  
     public abstract String getComponentType();
 91  
 
 92  
     public UIComponent getComponentInstance() {
 93  0
         return component;
 94  
     }
 95  
 
 96  
     public boolean getCreated() {
 97  1
         return created;
 98  
     }
 99  
 
 100  
     protected void setCreated(final boolean created) {
 101  0
         this.created = created;
 102  0
     }
 103  
 
 104  
     public static UIComponentTag getParentUIComponentTag(
 105  
             final PageContext context) {
 106  16
         final List list = PageContextUtil
 107  
                 .getComponentTagStackAttribute(context);
 108  16
         if (list != null) {
 109  1
             return ((UIComponentTag) list.get(list.size() - 1));
 110  
         } else {
 111  15
             return null;
 112  
         }
 113  
     }
 114  
 
 115  
     public abstract String getRendererType();
 116  
 
 117  
     public static boolean isValueReference(final String value) {
 118  131
         AssertionUtil.assertNotNull("value", value);
 119  130
         if ((value.indexOf("#{") != -1) &&
 120  
                 (value.indexOf("#{") < value.indexOf('}'))) {
 121  39
             return true;
 122  
         }
 123  91
         return false;
 124  
     }
 125  
 
 126  
     public void setPageContext(final PageContext pageContext) {
 127  10
         this.pageContext = pageContext;
 128  10
     }
 129  
 
 130  
     public Tag getParent() {
 131  10
         return parent;
 132  
     }
 133  
 
 134  
     public void setParent(final Tag parent) {
 135  8
         this.parent = parent;
 136  8
     }
 137  
 
 138  
     public int doStartTag() throws JspException {
 139  7
         setupFacesContext();
 140  7
         setupResponseWriter();
 141  7
         final UIComponentTag parentTag = getParentUIComponentTag(pageContext);
 142  7
         Map componentIds = null;
 143  7
         if (parentTag == null) {
 144  7
             componentIds = new HashMap();
 145  7
             pageContext.setAttribute(InternalConstants.GLOBAL_ID_VIEW,
 146  
                     componentIds, PageContext.REQUEST_SCOPE);
 147  
         } else {
 148  0
             componentIds = (Map) pageContext
 149  
                     .getAttribute(InternalConstants.GLOBAL_ID_VIEW,
 150  
                             PageContext.REQUEST_SCOPE);
 151  
         }
 152  7
         component = findComponent(context);
 153  
 
 154  7
         boolean isAlreadyTagInstanced = false;
 155  7
         String clientId = null;
 156  7
         if (id != null) {
 157  0
             clientId = component.getClientId(context);
 158  0
             isAlreadyTagInstanced = (componentIds.get(clientId) == this);
 159  
 
 160  0
             if (!isAlreadyTagInstanced && (clientId != null)) {
 161  0
                 if (!componentIds.containsKey(clientId)) {
 162  0
                     componentIds.put(clientId, this);
 163  
                 } else {
 164  0
                     throw new JspException(new IllegalStateException(
 165  
                             "Duplicate component id: '" +
 166  
                                     clientId +
 167  
                                     "', first used in tag: '" +
 168  
                                     componentIds.get(clientId).getClass()
 169  
                                             .getName() + "'"));
 170  
                 }
 171  
             }
 172  
         }
 173  
 
 174  7
         if (!isAlreadyTagInstanced && (parentTag != null)) {
 175  0
             if (getFacetName() == null) {
 176  0
                 parentTag.addChild(component);
 177  
             } else {
 178  0
                 parentTag.addFacet(getFacetName());
 179  
             }
 180  
         }
 181  
 
 182  
         try {
 183  7
             if (!isSuppressed() && !component.getRendersChildren()) {
 184  7
                 encodeBegin();
 185  7
                 context.getResponseWriter().flush();
 186  
             }
 187  0
         } catch (final IOException e) {
 188  0
             component = null;
 189  0
             context = null;
 190  0
             throw new JspException(e);
 191  7
         }
 192  7
         pushUIComponentTag();
 193  7
         return getDoStartValue();
 194  
     }
 195  
 
 196  
     public void setupFacesContext() throws JspException {
 197  7
         if (context != null) {
 198  0
             return;
 199  
         }
 200  7
         context = PageContextUtil.getCurrentFacesContextAttribute(pageContext);
 201  7
         if (context == null) {
 202  7
             context = FacesContext.getCurrentInstance();
 203  7
             if (context == null) {
 204  0
                 throw new JspException("Cannot find FacesContext");
 205  
             }
 206  7
             PageContextUtil.setCurrentFacesContextAttribute(pageContext,
 207  
                     context);
 208  
         }
 209  7
     }
 210  
 
 211  
     public int doEndTag() throws JspException {
 212  3
         popUIComponentTag();
 213  3
         removeOldChildren();
 214  3
         removeOldFacets();
 215  
         try {
 216  3
             if (!isSuppressed()) {
 217  3
                 if (component.getRendersChildren()) {
 218  0
                     encodeBegin();
 219  0
                     encodeChildren();
 220  
                 }
 221  3
                 encodeEnd();
 222  
             }
 223  0
         } catch (final IOException e) {
 224  0
             throw new JspException(e);
 225  
         } finally {
 226  3
             component = null;
 227  3
             context = null;
 228  3
         }
 229  3
         created = false;
 230  3
         return getDoEndValue();
 231  
     }
 232  
 
 233  
     public void release() {
 234  16
         component = null;
 235  16
         context = null;
 236  16
         created = false;
 237  16
         createdComponents = null;
 238  16
         createdFacets = null;
 239  16
         pageContext = null;
 240  16
         parent = null;
 241  16
         binding = null;
 242  16
         id = null;
 243  16
         rendered = null;
 244  16
     }
 245  
 
 246  
     protected void encodeBegin() throws IOException {
 247  7
         component.encodeBegin(context);
 248  7
     }
 249  
 
 250  
     protected void encodeChildren() throws IOException {
 251  0
         component.encodeChildren(context);
 252  0
     }
 253  
 
 254  
     protected void encodeEnd() throws IOException {
 255  3
         component.encodeEnd(context);
 256  3
     }
 257  
 
 258  
     public UIComponent findComponent(final FacesContext context)
 259  
             throws JspException {
 260  7
         if (component != null) {
 261  0
             return component;
 262  
         }
 263  7
         final UIComponentTag parentTag = getParentUIComponentTag(pageContext);
 264  7
         if (parentTag != null) {
 265  0
             final UIComponent parentComponent = parentTag
 266  
                     .getComponentInstance();
 267  0
             final String newId = createNewId();
 268  
 
 269  0
             final String facetName = getFacetName();
 270  0
             if (facetName != null) {
 271  0
                 component = (UIComponent) parentComponent.getFacets().get(
 272  
                         facetName);
 273  0
                 if (component == null) {
 274  0
                     component = createFacet(context, parentComponent,
 275  
                             facetName, newId);
 276  0
                     created = true;
 277  
                 }
 278  
             } else {
 279  0
                 component = getChild(parentComponent, newId);
 280  0
                 if (component == null) {
 281  0
                     component = createChild(context, parentComponent, newId);
 282  0
                     created = true;
 283  
                 }
 284  
             }
 285  0
             return component;
 286  
         } else {
 287  
             //special case(almost for UIViewRoot).
 288  7
             component = findComponentSpecially(context);
 289  7
             return component;
 290  
         }
 291  
     }
 292  
 
 293  
     private UIComponent findComponentSpecially(final FacesContext context) {
 294  7
         UIViewRoot parentComponent = PageContextUtil
 295  
                 .getCurrentViewRootAttribute(pageContext);
 296  7
         if (parentComponent == null) {
 297  7
             parentComponent = context.getViewRoot();
 298  7
             PageContextUtil.setCurrentViewRootAttribute(pageContext,
 299  
                     parentComponent);
 300  7
             if (parentComponent.getAttributes().get(
 301  
                     InternalConstants.CURRENT_VIEW_ROOT) == null) {
 302  7
                 setProperties(parentComponent);
 303  7
                 if (id != null) {
 304  0
                     parentComponent.setId(id);
 305  
                 }
 306  7
                 parentComponent.getAttributes().put(
 307  
                         InternalConstants.CURRENT_VIEW_ROOT,
 308  
                         InternalConstants.CURRENT_VIEW_ROOT);
 309  0
             } else if (binding == null) {
 310  0
                 setProperties(parentComponent);
 311  
             }
 312  
         }
 313  7
         return parentComponent;
 314  
     }
 315  
 
 316  
     protected int getDoEndValue() throws JspException {
 317  3
         return EVAL_PAGE;
 318  
     }
 319  
 
 320  
     protected int getDoStartValue() throws JspException {
 321  0
         return EVAL_BODY_INCLUDE;
 322  
     }
 323  
 
 324  
     protected FacesContext getFacesContext() {
 325  0
         return context;
 326  
     }
 327  
 
 328  
     protected String getFacetName() {
 329  10
         final Tag parent = getParent();
 330  10
         if (parent instanceof FacetTag) {
 331  0
             return ((FacetTag) parent).getName();
 332  
         } else {
 333  10
             return null;
 334  
         }
 335  
     }
 336  
 
 337  
     protected String getId() {
 338  0
         return id;
 339  
     }
 340  
 
 341  
     protected boolean isSuppressed() {
 342  10
         if (getFacetName() != null) {
 343  0
             return true;
 344  
         }
 345  10
         if (!component.isRendered()) {
 346  0
             return true;
 347  
         }
 348  10
         for (UIComponent c = component.getParent(); c != null; c = c
 349  
                 .getParent()) {
 350  0
             if (!c.isRendered() || c.getRendersChildren()) {
 351  0
                 return true;
 352  
             }
 353  
         }
 354  10
         return false;
 355  
     }
 356  
 
 357  
     protected void setProperties(final UIComponent component) {
 358  44
         if (rendered != null) {
 359  0
             if (isValueReference(rendered)) {
 360  0
                 component.setValueBinding("rendered", ValueBindingUtil
 361  
                         .createValueBinding(context, rendered));
 362  
             } else {
 363  0
                 component.setRendered(Boolean.valueOf(rendered).booleanValue());
 364  
             }
 365  
         }
 366  44
         if (getRendererType() != null) {
 367  32
             component.setRendererType(getRendererType());
 368  
         }
 369  44
     }
 370  
 
 371  
     protected void setupResponseWriter() {
 372  7
         ResponseWriter writer = context.getResponseWriter();
 373  7
         if (writer == null) {
 374  0
             writer = WebAppUtil.buildResponseWriter(context, pageContext);
 375  0
             context.setResponseWriter(writer);
 376  
         }
 377  7
     }
 378  
 
 379  
     private void addChild(final UIComponent child) {
 380  0
         if (createdComponents == null) {
 381  0
             createdComponents = new ArrayList();
 382  
         }
 383  0
         createdComponents.add(child.getId());
 384  0
     }
 385  
 
 386  
     private void addFacet(final String name) {
 387  0
         if (createdFacets == null) {
 388  0
             createdFacets = new ArrayList();
 389  
         }
 390  0
         createdFacets.add(name);
 391  0
     }
 392  
 
 393  
     protected UIComponent createComponent(final FacesContext context,
 394  
             final String newId) {
 395  0
         final UIComponent component = WebAppUtil.createComponent(context,
 396  
                 binding, getComponentType());
 397  0
         component.setId(newId);
 398  0
         setProperties(component);
 399  0
         return component;
 400  
     }
 401  
 
 402  
     private UIComponent createChild(final FacesContext context,
 403  
             final UIComponent parent, final String componentId) {
 404  0
         final UIComponent component = createComponent(context, componentId);
 405  0
         parent.getChildren().add(component);
 406  0
         return component;
 407  
     }
 408  
 
 409  
     protected UIComponent createFacet(final FacesContext context,
 410  
             final UIComponent parent, final String name, final String newId) {
 411  0
         final UIComponent component = createComponent(context, newId);
 412  0
         parent.getFacets().put(name, component);
 413  0
         return component;
 414  
     }
 415  
 
 416  
     private UIComponent getChild(final UIComponent component,
 417  
             final String componentId) {
 418  0
         for (final Iterator children = component.getChildren().iterator(); children
 419  0
                 .hasNext();) {
 420  0
             final UIComponent child = (UIComponent) children.next();
 421  0
             if (componentId.equals(child.getId())) {
 422  0
                 return child;
 423  
             }
 424  
         }
 425  0
         return null;
 426  
     }
 427  
 
 428  
     public void popUIComponentTag() {
 429  3
         final List list = PageContextUtil
 430  
                 .getComponentTagStackAttribute(pageContext);
 431  3
         if (list != null) {
 432  3
             list.remove(list.size() - 1);
 433  3
             if (list.size() < 1) {
 434  3
                 PageContextUtil.removeComponentStackAttribute(pageContext);
 435  
             }
 436  
         }
 437  3
     }
 438  
 
 439  
     public void pushUIComponentTag() {
 440  7
         List list = PageContextUtil.getComponentTagStackAttribute(pageContext);
 441  7
         if (list == null) {
 442  7
             list = new ArrayList();
 443  7
             PageContextUtil.setComponentStackAttribute(pageContext, list);
 444  
         }
 445  7
         list.add(this);
 446  7
     }
 447  
 
 448  
     private void removeOldChildren() {
 449  3
         final List oldList = WebAppUtil.getCreatedComponentIds(component);
 450  3
         if (oldList == null) {
 451  3
             saveChildrenComponentAttribute();
 452  3
             return;
 453  
         }
 454  0
         for (final Iterator olds = oldList.iterator(); olds.hasNext();) {
 455  0
             final String old = (String) olds.next();
 456  0
             if ((createdComponents == null) || !createdComponents.contains(old)) {
 457  0
                 final UIComponent child = component.findComponent(old);
 458  0
                 if (child != null) {
 459  0
                     component.getChildren().remove(child);
 460  
                 }
 461  
             }
 462  
         }
 463  0
         saveChildrenComponentAttribute();
 464  0
     }
 465  
 
 466  
     private void removeOldFacets() {
 467  3
         final List oldList = WebAppUtil.getCreatedFacetNames(component);
 468  3
         if (oldList == null) {
 469  3
             saveFacetsComponentAttribute();
 470  3
             return;
 471  
         }
 472  0
         for (final Iterator olds = oldList.iterator(); olds.hasNext();) {
 473  0
             final String old = (String) olds.next();
 474  0
             if ((createdFacets == null) || !createdFacets.contains(old)) {
 475  0
                 component.getFacets().remove(old);
 476  
             }
 477  
         }
 478  0
         saveFacetsComponentAttribute();
 479  0
     }
 480  
 
 481  
     private void saveChildrenComponentAttribute() {
 482  3
         if (createdComponents != null) {
 483  0
             WebAppUtil.setCreatedComponentIds(component, createdComponents);
 484  
         } else {
 485  3
             WebAppUtil.removeCreatedComponentIds(component);
 486  
         }
 487  3
         createdComponents = null;
 488  3
     }
 489  
 
 490  
     private void saveFacetsComponentAttribute() {
 491  3
         if (createdFacets != null) {
 492  0
             WebAppUtil.setCreatedFacetNames(component, createdFacets);
 493  
         } else {
 494  3
             WebAppUtil.removeCreatedFacetNames(component);
 495  
         }
 496  3
         createdFacets = null;
 497  3
     }
 498  
 
 499  
     private String createNewId() {
 500  0
         if (id == null) {
 501  0
             final FacesContext context = PageContextUtil
 502  
                     .getCurrentFacesContextAttribute(pageContext);
 503  0
             UIViewRoot viewRoot = context.getViewRoot();
 504  0
             if (viewRoot == null) {
 505  0
                 viewRoot = PageContextUtil
 506  
                         .getCurrentViewRootAttribute(pageContext);
 507  
             }
 508  0
             return viewRoot.createUniqueId();
 509  
         } else {
 510  0
             return id;
 511  
         }
 512  
     }
 513  
 
 514  
 }