Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]

    1   /*
    2    * $Id: UIForm.java,v 1.54 2008/02/22 01:49:30 rlubke Exp $
    3    */
    4   
    5   /*
    6    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    7    * 
    8    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    9    * 
   10    * The contents of this file are subject to the terms of either the GNU
   11    * General Public License Version 2 only ("GPL") or the Common Development
   12    * and Distribution License("CDDL") (collectively, the "License").  You
   13    * may not use this file except in compliance with the License. You can obtain
   14    * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   15    * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   16    * language governing permissions and limitations under the License.
   17    * 
   18    * When distributing the software, include this License Header Notice in each
   19    * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   20    * Sun designates this particular file as subject to the "Classpath" exception
   21    * as provided by Sun in the GPL Version 2 section of the License file that
   22    * accompanied this code.  If applicable, add the following below the License
   23    * Header, with the fields enclosed by brackets [] replaced by your own
   24    * identifying information: "Portions Copyrighted [year]
   25    * [name of copyright owner]"
   26    * 
   27    * Contributor(s):
   28    * 
   29    * If you wish your version of this file to be governed by only the CDDL or
   30    * only the GPL Version 2, indicate your decision by adding "[Contributor]
   31    * elects to include this software in this distribution under the [CDDL or GPL
   32    * Version 2] license."  If you don't indicate a single choice of license, a
   33    * recipient has the option to distribute your version of this file under
   34    * either the CDDL, the GPL Version 2 or to extend the choice of license to
   35    * its licensees as provided above.  However, if you add GPL Version 2 code
   36    * and therefore, elected the GPL Version 2 license, then the option applies
   37    * only if the new code is made subject to such option by the copyright
   38    * holder.
   39    */
   40   
   41   package javax.faces.component;
   42   
   43   import java.util.Collection;
   44   import java.util.Iterator;
   45   import javax.faces.application.Application;
   46   import javax.faces.component.visit.VisitCallback;
   47   import javax.faces.component.visit.VisitContext;
   48   import javax.faces.component.visit.VisitResult;
   49   import javax.faces.context.FacesContext;
   50   import javax.faces.event.PostValidateEvent;
   51   import javax.faces.event.PreValidateEvent;
   52   
   53   
   54   /**
   55    * <p><strong>UIForm</strong> is a {@link UIComponent} that represents an
   56    * input form to be presented to the user, and whose child components represent
   57    * (among other things) the input fields to be included when the form is
   58    * submitted.</p>
   59    * <p/>
   60    * <p>By default, the <code>rendererType</code> property must be set to
   61    * "<code>javax.faces.Form</code>".  This value can be changed by calling the
   62    * <code>setRendererType()</code> method.</p>
   63    */
   64   
   65   public class UIForm extends UIComponentBase implements NamingContainer, UniqueIdVendor {
   66   
   67   
   68       // ------------------------------------------------------ Manifest Constants
   69   
   70   
   71       /**
   72        * <p>The standard component type for this component.</p>
   73        */
   74       public static final String COMPONENT_TYPE = "javax.faces.Form";
   75   
   76   
   77       /**
   78        * <p>The standard component family for this component.</p>
   79        */
   80       public static final String COMPONENT_FAMILY = "javax.faces.Form";
   81   
   82   
   83       /**
   84        * Properties that are tracked by state saving.
   85        */
   86       enum PropertyKeys {
   87   
   88           /**
   89            * <p>The prependId flag.</p>
   90            */
   91           prependId,
   92   
   93           /**
   94            * <p>Last id vended by {@link UIForm#createUniqueId(javax.faces.context.FacesContext, String)}.</p>
   95            */
   96           lastId
   97       }
   98   
   99   
  100       // ------------------------------------------------------------ Constructors
  101   
  102   
  103       /**
  104        * <p>Create a new {@link UIForm} instance with default property
  105        * values.</p>
  106        */
  107       public UIForm() {
  108   
  109           super();
  110           setRendererType("javax.faces.Form");
  111   
  112       }
  113   
  114   
  115       // ------------------------------------------------------ Instance Variables
  116   
  117       //private int lastId = 0;
  118   
  119       // -------------------------------------------------------------- Properties
  120   
  121   
  122       public String getFamily() {
  123   
  124           return (COMPONENT_FAMILY);
  125   
  126       }
  127   
  128   
  129       /**
  130        * <p>The form submitted flag for this {@link UIForm}.</p>
  131        */
  132       private boolean submitted = false;
  133   
  134   
  135       /**
  136        * <p>Returns the current value of the <code>submitted</code>
  137        * property.  The default value is <code>false</code>.  See {@link
  138        * #setSubmitted} for details.</p>
  139        */
  140       public boolean isSubmitted() {
  141   
  142           return (this.submitted);
  143   
  144       }
  145   
  146   
  147       /**
  148        * <p>If <strong>this</strong> <code>UIForm</code> instance (as
  149        * opposed to other forms in the page) is experiencing a submit
  150        * during this request processing lifecycle, this method must be
  151        * called, with <code>true</code> as the argument, during the {@link
  152        * UIComponent#decode} for this <code>UIForm</code> instance.  If
  153        * <strong>this</strong> <code>UIForm</code> instance is
  154        * <strong>not</strong> experiencing a submit, this method must be
  155        * called, with <code>false</code> as the argument, during the
  156        * {@link UIComponent#decode} for this <code>UIForm</code>
  157        * instance.</p>
  158        * <p/>
  159        * <p>The value of a <code>UIForm</code>'s submitted property must
  160        * not be saved as part of its state.</p>
  161        */
  162       public void setSubmitted(boolean submitted) {
  163   
  164           this.submitted = submitted;
  165   
  166       }
  167   
  168       /**
  169        * <p>The prependId flag.</p>
  170        */
  171       //private Boolean prependId;
  172   
  173   
  174       public boolean isPrependId() {
  175   
  176           return (Boolean) getStateHelper().eval(PropertyKeys.prependId, true);
  177   
  178       }
  179   
  180   
  181       public void setPrependId(boolean prependId) {
  182   
  183           getStateHelper().put(PropertyKeys.prependId, prependId);
  184   
  185       }
  186   
  187       // ----------------------------------------------------- UIComponent Methods
  188   
  189   
  190       /**
  191        * <p>Override {@link UIComponent#processDecodes} to ensure that the
  192        * form is decoded <strong>before</strong> its children.  This is
  193        * necessary to allow the <code>submitted</code> property to be
  194        * correctly set.</p>
  195        *
  196        * @throws NullPointerException {@inheritDoc}
  197        */
  198       public void processDecodes(FacesContext context) {
  199   
  200           if (context == null) {
  201               throw new NullPointerException();
  202           }
  203   
  204           // Process this component itself
  205           decode(context);
  206   
  207           // if we're not the submitted form, don't process children.
  208           if (!isSubmitted()) {
  209               return;
  210           }
  211   
  212           // Process all facets and children of this component
  213           Iterator kids = getFacetsAndChildren();
  214           while (kids.hasNext()) {
  215               UIComponent kid = (UIComponent) kids.next();
  216               kid.processDecodes(context);
  217           }
  218   
  219       }
  220   
  221   
  222       /**
  223        * <p>Override {@link UIComponent#processValidators} to ensure that
  224        * the children of this <code>UIForm</code> instance are only
  225        * processed if {@link #isSubmitted} returns <code>true</code>.</p>
  226        *
  227        * @throws NullPointerException {@inheritDoc}
  228        */
  229       public void processValidators(FacesContext context) {
  230   
  231           if (context == null) {
  232               throw new NullPointerException();
  233           }
  234           if (!isSubmitted()) {
  235               return;
  236           }
  237           Application app = context.getApplication();
  238           app.publishEvent(context, PreValidateEvent.class, this);
  239           // Process all the facets and children of this component
  240           Iterator kids = getFacetsAndChildren();
  241           while (kids.hasNext()) {
  242               UIComponent kid = (UIComponent) kids.next();
  243               kid.processValidators(context);
  244           }
  245           app.publishEvent(context, PostValidateEvent.class, this);
  246   
  247       }
  248   
  249   
  250       /**
  251        * <p>Override {@link UIComponent#processUpdates} to ensure that the
  252        * children of this <code>UIForm</code> instance are only processed
  253        * if {@link #isSubmitted} returns <code>true</code>.</p>
  254        *
  255        * @throws NullPointerException {@inheritDoc}
  256        */
  257       public void processUpdates(FacesContext context) {
  258   
  259           if (context == null) {
  260               throw new NullPointerException();
  261           }
  262           if (!isSubmitted()) {
  263               return;
  264           }
  265   
  266           // Process all facets and children of this component
  267           Iterator kids = getFacetsAndChildren();
  268           while (kids.hasNext()) {
  269               UIComponent kid = (UIComponent) kids.next();
  270               kid.processUpdates(context);
  271           }
  272   
  273       }
  274   
  275       public String createUniqueId(FacesContext context, String seed) {
  276           Integer i = (Integer) getStateHelper().get(PropertyKeys.lastId);
  277           int lastId = ((i != null) ? i : 0);
  278           getStateHelper().put(PropertyKeys.lastId,  ++lastId);
  279           return UIViewRoot.UNIQUE_ID_PREFIX + (seed == null ? lastId : seed);
  280       }
  281       
  282       /**
  283        * <p>Override the {@link UIComponent#getContainerClientId} to allow
  284        * users to disable this form from prepending its <code>clientId</code> to
  285        * its descendent's <code>clientIds</code> depending on the value of
  286        * this form's {@link #isPrependId} property.</p>
  287        */
  288       public String getContainerClientId(FacesContext context) {
  289           if (this.isPrependId()) {
  290               return super.getContainerClientId(context);
  291           } else {
  292               UIComponent parent = this.getParent();
  293               while (parent != null) {
  294                   if (parent instanceof NamingContainer) {
  295                       return parent.getContainerClientId(context);
  296                   }
  297                   parent = parent.getParent();
  298               }
  299           }
  300           return null;
  301       }
  302   
  303      
  304       /**
  305        * @see UIComponent#visitTree
  306        */
  307       @Override
  308       public boolean visitTree(VisitContext context,
  309                                VisitCallback callback) {
  310   
  311           // NamingContainers can optimize partial tree visits by taking advantage
  312           // of the fact that it is possible to detect whether any ids to visit
  313           // exist underneath the NamingContainer.  If no such ids exist, there
  314           // is no need to visit the subtree under the NamingContainer.
  315   
  316           // UIForm is a bit different from other NamingContainers.  It only acts
  317           // as a NamingContainer when prependId is true.  Note that if it 
  318           // weren't for this, we could push this implementation up in to
  319           // UIComponent and share it across all NamingContainers.  Instead,
  320           // we currently duplicate this implementation in UIForm and 
  321           // UINamingContainer, so that we can check isPrependId() here.
  322   
  323           if (!this.isPrependId()) {
  324               return super.visitTree(context, callback);
  325           }
  326   
  327           Collection<String> idsToVisit = context.getSubtreeIdsToVisit(this);
  328           assert (idsToVisit != null);
  329   
  330           // If we have ids to visit, let the superclass implementation
  331           // handle the visit
  332           if (!idsToVisit.isEmpty()) {
  333               return super.visitTree(context, callback);
  334           }
  335   
  336           // If we have no child ids to visit, just visit ourselves, if
  337           // we are visitable.
  338           if (isVisitable(context)) {
  339               FacesContext facesContext = context.getFacesContext();
  340               pushComponentToEL(facesContext, null);
  341   
  342               try {
  343                   VisitResult result = context.invokeVisitCallback(this, callback);
  344                   return (result == VisitResult.COMPLETE);
  345               }
  346               finally {
  347                   popComponentFromEL(facesContext);
  348               }
  349           }
  350   
  351           // Done visiting this subtree.  Return false to allow 
  352           // visit to continue.
  353           return false;
  354       }
  355   }
  356   

Home » Mojarra-2.0.1 » javax » faces » component » [javadoc | source]