Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    * 
    * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
    * 
    * The contents of this file are subject to the terms of either the GNU
    * General Public License Version 2 only ("GPL") or the Common Development
    * and Distribution License("CDDL") (collectively, the "License").  You
    * may not use this file except in compliance with the License. You can obtain
   * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
   * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
   * language governing permissions and limitations under the License.
   * 
   * When distributing the software, include this License Header Notice in each
   * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
   * Sun designates this particular file as subject to the "Classpath" exception
   * as provided by Sun in the GPL Version 2 section of the License file that
   * accompanied this code.  If applicable, add the following below the License
   * Header, with the fields enclosed by brackets [] replaced by your own
   * identifying information: "Portions Copyrighted [year]
   * [name of copyright owner]"
   * 
   * Contributor(s):
   * 
   * If you wish your version of this file to be governed by only the CDDL or
   * only the GPL Version 2, indicate your decision by adding "[Contributor]
   * elects to include this software in this distribution under the [CDDL or GPL
   * Version 2] license."  If you don't indicate a single choice of license, a
   * recipient has the option to distribute your version of this file under
   * either the CDDL, the GPL Version 2 or to extend the choice of license to
   * its licensees as provided above.  However, if you add GPL Version 2 code
   * and therefore, elected the GPL Version 2 license, then the option applies
   * only if the new code is made subject to such option by the copyright
   * holder.
   */
  
  package javax.faces.component;
  
  import  javax.servlet.jsp.jstl.sql.Result;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;


UIData is a UIComponent that supports data binding to a collection of data objects represented by a DataModel instance, which is the current value of this component itself (typically established via a ValueExpression). During iterative processing over the rows of data in the data model, the object for the current row is exposed as a request attribute under the key specified by the var property.

Only children of type UIColumn should be processed by renderers associated with this component.

By default, the rendererType property is set to javax.faces.Table. This value can be changed by calling the setRendererType() method.

  
  
  public class UIData extends UIComponentBase
        implements NamingContainer {
  
      // ------------------------------------------------------ Manifest Constants
  

    

The standard component type for this component.

  
      public static final String COMPONENT_TYPE = "javax.faces.Data";


    

The standard component family for this component.

  
      public static final String COMPONENT_FAMILY = "javax.faces.Data";
 
     // ------------------------------------------------------------ Constructors
 

    

Create a new UIData instance with default property values.

 
     public UIData() {
 
         super();
         setRendererType("javax.faces.Table");
 
     }
 
     // ------------------------------------------------------ Instance Variables
 

    

The first row number (zero-relative) to be displayed.

 
     private Integer first;


    

The DataModel associated with this component, lazily instantiated if requested. This object is not part of the saved and restored state of the component.

 
     private DataModel model = null;


    

During iteration through the rows of this table, This ivar is used to store the previous "var" value for this instance. When the row iteration is complete, this value is restored to the request map.

 
     private Object oldVar;


    

The zero-relative index of the current row number, or -1 for no current row association.

 
     private int rowIndex = -1;


    

The number of rows to display, or zero for all remaining rows in the table.

 
     private Integer rows;


    

This map contains SavedState instances for each descendant component, keyed by the client identifier of the descendant. Because descendant client identifiers will contain the rowIndex value of the parent, per-row state information is actually preserved.

 
     @SuppressWarnings({"CollectionWithoutInitialCapacity"})
     private Map<StringSavedStatesaved = new HashMap<StringSavedState>();


    

The local value of this UIComponent.

 
     private Object value = null;


    

The request scope attribute under which the data object for the current row will be exposed when iterating.

 
     private String var = null;


    

Holds the base client ID that will be used to generate per-row client IDs (this will be null if this UIData is nested within another).

This is not part of the component state.

 
     private String baseClientId = null;


    

Length of the cached baseClientId plus one for the NamingContainer.SEPARATOR_CHAR.

This is not part of the component state.

 
     private int baseClientIdLength;


    

StringBuilder used to build per-row client IDs.

This is not part of the component state.

 
     private StringBuilder clientIdBuilder = null;


    

Flag indicating whether or not this UIData instance is nested within another UIData instance

This is not part of the component state.

 
     private Boolean isNested = null;
     
 
     // -------------------------------------------------------------- Properties
 
 
     public String getFamily() {
 
         return ();
 
     }


    

Return the zero-relative row number of the first row to be displayed.

 
     public int getFirst() {
 
         if (this. != null) {
             return (this.);
         }
         ValueExpression ve = getValueExpression("first");
         if (ve != null) {
             Integer value;
             try {
                 value = (Integerve.getValue(getFacesContext().getELContext());
             }
             catch (ELException e) {
                 throw new FacesException(e);
             }
             if (null == value) {
                 return ;
             }
             return (value.intValue());
         } else {
             return (0);
         }
 
     }


    

Set the zero-relative row number of the first row to be displayed.

Parameters:
first New first row number
Throws:
IllegalArgumentException if first is negative
 
     public void setFirst(int first) {
 
         if (first < 0) {
             throw new IllegalArgumentException(String.valueOf(first));
         }
         this. = first;
 
     }


    

Return the footer facet of this component (if any). A convenience method for getFacet("footer").

 
     public UIComponent getFooter() {
 
         return getFacet("footer");
 
     }


    

Set the footer facet of this component. A convenience method for getFacets().put("footer", footer).

Parameters:
footer the new footer facet
Throws:
NullPointerException if footer is null
 
     public void setFooter(UIComponent footer) {
 
         getFacets().put("footer"footer);
 
     }


    

Return the header facet of this component (if any). A convenience method for getFacet("header").

 
     public UIComponent getHeader() {
 
         return getFacet("header");
 
     }


    

Set the header facet of this component. A convenience method for getFacets().put("header", header).

Parameters:
header the new header facet
Throws:
NullPointerException if header is null
 
     public void setHeader(UIComponent header) {
 
         getFacets().put("header"header);
 
     }


    

Return a flag indicating whether there is rowData available at the current rowIndex. If no wrappedData is available, return false.

Throws:
FacesException if an error occurs getting the row availability
 
     public boolean isRowAvailable() {
 
         return (getDataModel().isRowAvailable());
 
     }


    

Return the number of rows in the underlying data model. If the number of available rows is unknown, return -1.

Throws:
FacesException if an error occurs getting the row count
 
     public int getRowCount() {
 
         return (getDataModel().getRowCount());
 
     }


    

Return the data object representing the data for the currently selected row index, if any.

Throws:
FacesException if an error occurs getting the row data
IllegalArgumentException if now row data is available at the currently specified row index
 
     public Object getRowData() {
 
         return (getDataModel().getRowData());
 
     }


    

Return the zero-relative index of the currently selected row. If we are not currently positioned on a row, return -1. This property is not enabled for value binding expressions.

Throws:
FacesException if an error occurs getting the row index
 
     public int getRowIndex() {
 
         return (this.);
 
     }


    

Set the zero relative index of the current row, or -1 to indicate that no row is currently selected, by implementing the following algorithm. It is possible to set the row index at a value for which the underlying data collection does not contain any row data. Therefore, callers may use the isRowAvailable() method to detect whether row data will be available for use by the getRowData() method.

  • Save current state information for all descendant components (as described below).
  • Store the new row index, and pass it on to the DataModel associated with this UIData instance.
  • If the new rowIndex value is -1:
    • If the var property is not null, remove the corresponding request scope attribute (if any).
    • Reset the state information for all descendant components (as described below).
  • If the new rowIndex value is not -1:
    • If the var property is not null, call getRowData() and expose the resulting data object as a request scope attribute whose key is the var property value.
    • Reset the state information for all descendant components (as described below).

To save current state information for all descendant components, UIData must maintain per-row information for each descendant as follows:

  • If the descendant is an instance of EditableValueHolder, save the state of its localValue property.
  • If the descendant is an instance of EditableValueHolder, save the state of the localValueSet property.
  • If the descendant is an instance of EditableValueHolder, save the state of the valid property.
  • If the descendant is an instance of EditableValueHolder, save the state of the submittedValue property.

To restore current state information for all descendant components, UIData must reference its previously stored information for the current rowIndex and call setters for each descendant as follows:

  • If the descendant is an instance of EditableValueHolder, restore the value property.
  • If the descendant is an instance of EditableValueHolder, restore the state of the localValueSet property.
  • If the descendant is an instance of EditableValueHolder, restore the state of the valid property.
  • If the descendant is an instance of EditableValueHolder, restore the state of the submittedValue property.

Parameters:
rowIndex The new row index value, or -1 for no associated row
Throws:
FacesException if an error occurs setting the row index
IllegalArgumentException if rowIndex is less than -1
 
     public void setRowIndex(int rowIndex) {
 
         // Save current state for the previous row index
         saveDescendantState();
 
         // Update to the new row index        
         this. = rowIndex;
         DataModel localModel = getDataModel();
         localModel.setRowIndex(rowIndex);
 
         // Clear or expose the current row data as a request scope attribute
         if ( != null) {
             Map<StringObjectrequestMap =
                   getFacesContext().getExternalContext().getRequestMap();
             if (rowIndex == -1) {
                  = requestMap.remove();
             } else if (isRowAvailable()) {
                 requestMap.put(getRowData());
             } else {
                 requestMap.remove();
                 if (null != ) {
                     requestMap.put();
                      = null;
                 }
             }
         }
 
         // Reset current state information for the new row index
         restoreDescendantState();
 
     }


    

Return the number of rows to be displayed, or zero for all remaining rows in the table. The default value of this property is zero.

 
     public int getRows() {
 
         if (this. != null) {
             return (this.);
         }
         ValueExpression ve = getValueExpression("rows");
         if (ve != null) {
             Integer value;
             try {
                 value = (Integerve.getValue(getFacesContext().getELContext());
             }
             catch (ELException e) {
                 throw new FacesException(e);
             }
 
             if (null == value) {
                 return ;
             }
             return (value.intValue());
         } else {
             return (0);
         }
 
     }


    

Set the number of rows to be displayed, or zero for all remaining rows in the table.

Parameters:
rows New number of rows
Throws:
IllegalArgumentException if rows is negative
 
     public void setRows(int rows) {
 
         if (rows < 0) {
             throw new IllegalArgumentException(String.valueOf(rows));
         }
         this. = rows;
 
     }


    

Return the request-scope attribute under which the data object for the current row will be exposed when iterating. This property is not enabled for value binding expressions.

 
     public String getVar() {
 
         return (this.);
 
     }


    

Set the request-scope attribute under which the data object for the current row wil be exposed when iterating.

Parameters:
var The new request-scope attribute name
 
     public void setVar(String var) {
 
         this. = var;
 
     }
 
     // ----------------------------------------------------- StateHolder Methods
 
 
     private Object[] values;
 
     public Object saveState(FacesContext context) {
 
         if ( == null) {
              = new Object[7];
         }
 
         [0] = super.saveState(context);
         [1] = ;
         [2] = ;
         [3] = ;
         [4] = ;
         [5] = ;
         [6] = ;
         return ();
 
     }
 
 
     public void restoreState(FacesContext contextObject state) {
 
          = (Object[]) state;
         super.restoreState(context, values[0]);
          = (Integer[1];
          = (Integer[2];
          = (Integer[3];
          = TypedCollections
               .dynamicallyCastMap((Map[4], String.classSavedState.class);
          = [5];
          = (String[6];
 
     }


    

Return the value of the UIData. This value must either be be of type DataModel, or a type that can be adapted into a DataModel. UIData will automatically adapt the following types:

  • Arrays
  • java.util.List
  • java.sql.ResultSet
  • javax.servlet.jsp.jstl.sql.Result

All other types will be adapted using the ScalarDataModel class, which will treat the object as a single row of data.

 
     public Object getValue() {
 
         if (this. != null) {
             return (this.);
         }
         ValueExpression ve = getValueExpression("value");
         if (ve != null) {
             try {
                 return (ve.getValue(getFacesContext().getELContext()));
             }
             catch (ELException e) {
                 throw new FacesException(e);
             }
 
         } else {
             return (null);
         }
 
     }


    

Set the value of the UIData. This value must either be be of type DataModel, or a type that can be adapted into a DataModel.

Parameters:
value the new value
 
     public void setValue(Object value) {
         setDataModel(null);
         this. = value;
 
     }
 
     // ----------------------------------------------------- UIComponent Methods
 

    

If "name" is something other than "value", "var", or "rowIndex", rely on the superclass conversion from ValueBinding to ValueExpression.

Deprecated:
This has been replaced by setValueExpression(java.lang.String, javax.el.ValueExpression).
Parameters:
name Name of the attribute or property for which to set a ValueBinding
binding The ValueBinding to set, or null to remove any currently set ValueBinding
Throws:
IllegalArgumentException if name is one of id, parent, var, or rowIndex
NullPointerException if name is null
 
     public void setValueBinding(String nameValueBinding binding) {
 
         if ("value".equals(name)) {
             setDataModel(null);
         } else if ("var".equals(name) || "rowIndex".equals(name)) {
             throw new IllegalArgumentException();
         }
         super.setValueBinding(namebinding);
 
     }

    

Set the ValueExpression used to calculate the value for the specified attribute or property name, if any. In addition, if a ValueExpression is set for the value property, remove any synthesized DataModel for the data previously bound to this component.

Parameters:
name Name of the attribute or property for which to set a ValueExpression
binding The ValueExpression to set, or null to remove any currently set ValueExpression
Throws:
IllegalArgumentException if name is one of id, parent, var, or rowIndex
NullPointerException if name is null
Since:
1.2
 
     public void setValueExpression(String nameValueExpression binding) {
 
         if ("value".equals(name)) {
             this. = null;
         } else if ("var".equals(name) || "rowIndex".equals(name)) {
             throw new IllegalArgumentException();
         }
         super.setValueExpression(namebinding);
 
     }

    

Return a client identifier for this component that includes the current value of the rowIndex property, if it is not set to -1. This implies that multiple calls to getClientId() may return different results, but ensures that child components can themselves generate row-specific client identifiers (since UIData is a NamingContainer).

Throws:
NullPointerException if context is null
 
     public String getClientId(FacesContext context) {
 
         if (context == null) {
             throw new NullPointerException();
         }
 
         // If baseClientId and clientIdBuilder are both null, this is the
         // first time that getClientId() has been called.
         // If we're not nested within another UIData, then:
         //   - create a new StringBuilder assigned to clientIdBuilder containing
         //   our client ID.
         //   - toString() the builder - this result will be our baseClientId
         //     for the duration of the component
         //   - append SEPARATOR_CHAR to the builder
         //  If we are nested within another UIData, then:
         //   - create an empty StringBuilder that will be used to build
         //     this instance's ID
         if ( == null &&  == null) {
             if (!isNestedWithinUIData()) {
                  = new StringBuilder(super.getClientId(context));
                  = .toString();
                  = (.length() + 1);
                 .append(.);
                 .setLength();
             } else {
                  = new StringBuilder();
             }
         }
         if ( >= 0) {
             String cid;
             if (!isNestedWithinUIData()) {
                 // we're not nested, so the clientIdBuilder is already
                 // primed with clientID + SEPARATOR_CHAR.  Append
                 // the current rowIndex, and toString() the builder.
                 // reset the builder to it's primed state.
                 cid = .append().toString();
                 .setLength();
             } else {
                 // we're nested, so we have to build the ID from scratch
                 // each time.  Reuse the same clientIdBuilder instance
                 // for each call by resetting the length to 0 after
                 // the ID has been computed.
                 cid = .append(super.getClientId(context))
                       .append(.).append()
                       .toString();
                 .setLength(0);
             }
             return (cid);
         } else {
             if (!isNestedWithinUIData()) {
                 // Not nested and no row available, so just return our baseClientId
                 return ();
             } else {
                 // nested and no row available, return the result of getClientId().
                 // this is necessary as the client ID will reflect the row that
                 // this table represents
                 return super.getClientId(context);
             }
         }
 
     }

    

Override behavior from UIComponentBase.invokeOnComponent to provide special care for positioning the data properly before finding the component and invoking the callback on it. If the argument clientId is equal to this.getClientId() simply invoke the contextCallback, passing the context argument and this as arguments, and return true. Otherwise, attempt to extract a rowIndex from the clientId. For example, if the argument clientId was form:data:3:customerHeader the rowIndex would be 3. Let this value be called newIndex. The current rowIndex of this instance must be saved aside and restored before returning in all cases, regardless of the outcome of the search or if any exceptions are thrown in the process.

The implementation of this method must never return true if setting the rowIndex of this instance to be equal to newIndex causes this instance to return false from isRowAvailable.

Throws:
NullPointerException
FacesException Also throws FacesException if any exception is thrown when deriving the rowIndex from the argument clientId.
Since:
1.2
 
     public boolean invokeOnComponent(FacesContext contextString clientId,
                                      ContextCallback callback)
           throws FacesException {
         if (null == context || null == clientId || null == callback) {
             throw new NullPointerException();
         }
 
         String myId = super.getClientId(context);
         boolean found = false;
         if (clientId.equals(myId)) {
             try {
                 callback.invokeContextCallback(contextthis);
                 return true;
             }
             catch (Exception e) {
                 throw new FacesException(e);
             }
         }
         int lastSepnewRowsavedRowIndex = this.getRowIndex();
         try {
             // If we need to strip out the rowIndex from our id
             // PENDING(edburns): is this safe with respect to I18N?
             if (myId.endsWith(String.valueOf(savedRowIndex))) {
                 lastSep = myId.lastIndexOf(.);
                 assert (-1 != lastSep);
                 myId = myId.substring(0, lastSep);
             }
 
             // myId will be something like form:outerData for a non-nested table,
             // and form:outerData:3:data for a nested table.
             // clientId will be something like form:outerData:3:outerColumn
             // for a non-nested table.  clientId will be something like
             // outerData:3:data:3:input for a nested table.
             if (clientId.startsWith(myId)) {
                 int preRowIndexSeppostRowIndexSep;
 
                 if (-1 != (preRowIndexSep =
                       clientId.indexOf(.,
                                        myId.length()))) {
                     // Check the length
                     if (++preRowIndexSep < clientId.length()) {
                         if (-1 != (postRowIndexSep =
                               clientId.indexOf(.,
                                                preRowIndexSep + 1))) {
                             try {
                                 newRow = Integer
                                       .valueOf(clientId.substring(preRowIndexSep,
                                                                   postRowIndexSep))
                                       .intValue();
                             } catch (NumberFormatException ex) {
                                 // PENDING(edburns): I18N
                                 String message =
                                       "Trying to extract rowIndex from clientId \'"
                                       +
                                       clientId
                                       + "\' "
                                       + ex.getMessage();
                                 throw new NumberFormatException(message);
                             }
                             this.setRowIndex(newRow);
                             if (this.isRowAvailable()) {
                                 found = super.invokeOnComponent(context,
                                                                 clientId,
                                                                 callback);
                             }
                         }
                     }
                 }
             }
         }
         catch (FacesException fe) {
             throw fe;
         }
         catch (Exception e) {
             throw new FacesException(e);
         }
         finally {
             this.setRowIndex(savedRowIndex);
         }
         return found;
     }


    

Override the default UIComponentBase.queueEvent processing to wrap any queued events in a wrapper so that we can reset the current row index in broadcast().

Parameters:
event FacesEvent to be queued
Throws:
IllegalStateException if this component is not a descendant of a UIViewRoot
NullPointerException if event is null
 
     public void queueEvent(FacesEvent event) {
 
         super.queueEvent(new WrapperEvent(this, event, getRowIndex()));
 
     }


    

Override the default UIComponentBase.broadcast processing to unwrap any wrapped FacesEvent and reset the current row index, before the event is actually broadcast. For events that we did not wrap (in queueEvent()), default processing will occur.

Parameters:
event The FacesEvent to be broadcast
Throws:
AbortProcessingException Signal the JavaServer Faces implementation that no further processing on the current event should be performed
IllegalArgumentException if the implementation class of this FacesEvent is not supported by this component
NullPointerException if event is null
 
     public void broadcast(FacesEvent event)
           throws AbortProcessingException {
 
         if (!(event instanceof WrapperEvent)) {
             super.broadcast(event);
             return;
         }
 
         // Set up the correct context and fire our wrapped event
         WrapperEvent revent = (WrapperEventevent;
         if (isNestedWithinUIData()) {
             setDataModel(null);
         }
         int oldRowIndex = getRowIndex();
         setRowIndex(revent.getRowIndex());
         FacesEvent rowEvent = revent.getFacesEvent();
         rowEvent.getComponent().broadcast(rowEvent);
         setRowIndex(oldRowIndex);
 
     }


    

In addition to the default behavior, ensure that any saved per-row state for our child input components is discarded unless it is needed to rerender the current page with errors.

Parameters:
context FacesContext for the current request
Throws:
IOException if an input/output error occurs while rendering
NullPointerException if context is null
 
     public void encodeBegin(FacesContext contextthrows IOException {
 
         setDataModel(null); // re-evaluate even with server-side state saving
         if (!keepSaved(context)) {
             //noinspection CollectionWithoutInitialCapacity
              = new HashMap<StringSavedState>();
         }
         super.encodeBegin(context);
 
     }


    

Override the default UIComponentBase.processDecodes processing to perform the following steps.

  • If the rendered property of this UIComponent is false, skip further processing.
  • Set the current rowIndex to -1.
  • Call the processDecodes() method of all facets of this UIData, in the order determined by a call to getFacets().keySet().iterator().
  • Call the processDecodes() method of all facets of the UIColumn children of this UIData.
  • Iterate over the set of rows that were included when this component was rendered (i.e. those defined by the first and rows properties), performing the following processing for each row:
    • Set the current rowIndex to the appropriate value for this row.
    • If isRowAvailable() returns true, iterate over the children components of each UIColumn child of this UIData component, calling the processDecodes() method for each such child.
  • Set the current rowIndex to -1.
  • Call the decode() method of this component.
  • If a RuntimeException is thrown during decode processing, call FacesContext.renderResponse and re-throw the exception.

Parameters:
context FacesContext for the current request
Throws:
NullPointerException if context is null
 
     public void processDecodes(FacesContext context) {
 
         if (context == null) {
             throw new NullPointerException();
         }
         if (!isRendered()) {
             return;
         }
 
         setDataModel(null); // Re-evaluate even with server-side state saving
         if (null ==  || !keepSaved(context)) {
             //noinspection CollectionWithoutInitialCapacity
              = new HashMap<StringSavedState>(); // We don't need saved state here
         }
 
         iterate(context.);
         decode(context);
    }


    

Override the default UIComponentBase.processValidators processing to perform the following steps.

  • If the rendered property of this UIComponent is false, skip further processing.
  • Set the current rowIndex to -1.
  • Call the processValidators() method of all facets of this UIData, in the order determined by a call to getFacets().keySet().iterator().
  • Call the processValidators() method of all facets of the UIColumn children of this UIData.
  • Iterate over the set of rows that were included when this component was rendered (i.e. those defined by the first and rows properties), performing the following processing for each row:
    • Set the current rowIndex to the appropriate value for this row.
    • If isRowAvailable() returns true, iterate over the children components of each UIColumn child of this UIData component, calling the processValidators() method for each such child.
  • Set the current rowIndex to -1.

Parameters:
context FacesContext for the current request
Throws:
NullPointerException if context is null
    public void processValidators(FacesContext context) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (!isRendered()) {
            return;
        }
        if (isNestedWithinUIData()) {
            setDataModel(null);
        }
        iterate(context.);
        // This is not a EditableValueHolder, so no further processing is required
    }


    

Override the default UIComponentBase.processUpdates processing to perform the following steps.

  • If the rendered property of this UIComponent is false, skip further processing.
  • Set the current rowIndex to -1.
  • Call the processUpdates() method of all facets of this UIData, in the order determined by a call to getFacets().keySet().iterator().
  • Call the processUpdates() method of all facets of the UIColumn children of this UIData.
  • Iterate over the set of rows that were included when this component was rendered (i.e. those defined by the first and rows properties), performing the following processing for each row:
    • Set the current rowIndex to the appropriate value for this row.
    • If isRowAvailable() returns true, iterate over the children components of each UIColumn child of this UIData component, calling the processUpdates() method for each such child.
  • Set the current rowIndex to -1.

Parameters:
context FacesContext for the current request
Throws:
NullPointerException if context is null
    public void processUpdates(FacesContext context) {
        if (context == null) {
            throw new NullPointerException();
        }
        if (!isRendered()) {
            return;
        }
        if (isNestedWithinUIData()) {
            setDataModel(null);
        }
        iterate(context.);
        // This is not a EditableValueHolder, so no further processing is required
    }
    // --------------------------------------------------------- Protected Methods


    

Return the internal DataModel object representing the data objects that we will iterate over in this component's rendering.

If the model has been cached by a previous call to setDataModel, return it. Otherwise call getValue. If the result is null, create an empty ListDataModel and return it. If the result is an instance of DataModel, return it. Otherwise, adapt the result as described in getValue and return it.

    protected DataModel getDataModel() {
        // Return any previously cached DataModel instance
        if (this. != null) {
            return ();
        }
        // Synthesize a DataModel around our current value if possible
        Object current = getValue();
        if (current == null) {
            setDataModel(new ListDataModel(.));
        } else if (current instanceof DataModel) {
            setDataModel((DataModelcurrent);
        } else if (current instanceof List) {
            setDataModel(new ListDataModel((Listcurrent));
        } else if (Object[].class.isAssignableFrom(current.getClass())) {
            setDataModel(new ArrayDataModel((Object[]) current));
        } else if (current instanceof ResultSet) {
            setDataModel(new ResultSetDataModel((ResultSetcurrent));
        } else if (current instanceof Result) {
            setDataModel(new ResultDataModel((Result) current));
        } else {
            setDataModel(new ScalarDataModel(current));
        }
        return ();
    }

    

Set the internal DataModel. This UIData instance must use the given DataModel as its internal value representation from now until the next call to setDataModel. If the given DataModel is null, the internal DataModel must be reset in a manner so that the next call to getDataModel causes lazy instantion of a newly refreshed DataModel.

Subclasses might call this method if they either want to restore the internal DataModel during the Restore View phase or if they want to explicitly refresh the current DataModel for the Render Response phase.

Parameters:
dataModel the new DataModel or null to cause the model to be refreshed.
    protected void setDataModel(DataModel dataModel) {
        this. = dataModel;
    }
    // ---------------------------------------------------- Private Methods


    

Perform the appropriate phase-specific processing and per-row iteration for the specified phase, as follows:

  • Set the rowIndex property to -1, and process the facets of this UIData component exactly once.
  • Set the rowIndex property to -1, and process the facets of the UIColumn children of this UIData component exactly once.
  • Iterate over the relevant rows, based on the first and row properties, and process the children of the UIColumn children of this UIData component once per row.

Parameters:
context FacesContext for the current request
phaseId PhaseId of the phase we are currently running
    private void iterate(FacesContext contextPhaseId phaseId) {
        // Process each facet of this component exactly once
        setRowIndex(-1);
        if (getFacetCount() > 0) {
            for (UIComponent facet : getFacets().values()) {
                if (phaseId == .) {
                    facet.processDecodes(context);
                } else if (phaseId == .) {
                    facet.processValidators(context);
                } else if (phaseId == .) {
                    facet.processUpdates(context);
                } else {
                    throw new IllegalArgumentException();
                }
            }
        }
        // Process each facet of our child UIColumn components exactly once
        setRowIndex(-1);
        if (getChildCount() > 0) {
            for (UIComponent column : getChildren()) {
                if (!(column instanceof UIColumn) || !column.isRendered()) {
                    continue;
                }
                if (column.getFacetCount() > 0) {
                    for (UIComponent columnFacet : column.getFacets().values()) {                      
                        if (phaseId == .) {
                            columnFacet.processDecodes(context);
                        } else if (phaseId == .) {
                            columnFacet.processValidators(context);
                        } else if (phaseId == .) {
                            columnFacet.processUpdates(context);
                        } else {
                            throw new IllegalArgumentException();
                        }
                    }
                }
            }
        }
        // Iterate over our UIColumn children, once per row
        int processed = 0;
        int rowIndex = getFirst() - 1;
        int rows = getRows();
        while (true) {
            // Have we processed the requested number of rows?
            if ((rows > 0) && (++processed > rows)) {
                break;
            }
            // Expose the current row in the specified request attribute
            setRowIndex(++rowIndex);
            if (!isRowAvailable()) {
                break// Scrolled past the last row
            }
            // Perform phase-specific processing as required
            // on the *children* of the UIColumn (facets have
            // been done a single time with rowIndex=-1 already)
            if (getChildCount() > 0) {
                for (UIComponent kid : getChildren()) {
                    if (!(kid instanceof UIColumn) || !kid.isRendered()) {
                        continue;
                    }
                    if (kid.getChildCount() > 0) {
                        for (UIComponent grandkid : kid.getChildren()) {
                            if (!grandkid.isRendered()) {
                                continue;
                            }
                            if (phaseId == .) {
                                grandkid.processDecodes(context);
                            } else if (phaseId == .) {
                                grandkid.processValidators(context);
                            } else if (phaseId == .) {
                                grandkid.processUpdates(context);
                            } else {
                                throw new IllegalArgumentException();
                            }
                        }
                    }
                }
            }
        }
        // Clean up after ourselves
        setRowIndex(-1);
    }


    

Return true if we need to keep the saved per-child state information. This will be the case if any of the following are true:

  • any of the saved state corresponds to components that have messages that must be displayed
  • this UIData instance is nested inside of another UIData instance

Parameters:
context FacesContext for the current request
    private boolean keepSaved(FacesContext context) {
        if (!isNestedWithinUIData()) {
            // The UIData instance is not nested.  Get all client IDs that have messages
            // and if any of them start with the the result of super.getClientId(),
            // then get the messages and see if any are ERROR or FATAL.  If any are found,
            // return true, otherwise false.
            String uiDataClientId = super.getClientId(context);
            for (Iterator<Stringids = context.getClientIdsWithMessages();
                  ids.hasNext();) {
                String id = ids.next();
                if (id == null) {
                    // getClientIdsWithMessages() will return a null element
                    // for messages that don't have client IDs - not sure why
                    // it was spec'd that way....
                    continue;
                }
                if (id.startsWith(uiDataClientId)) {
                    for (Iterator<FacesMessagemsgs = context.getMessages(id);
                          msgs.hasNext();) {
                        FacesMessage msg = msgs.next();
                        if (..compareTo(msg.getSeverity()) >= 0) {
                            return true;
                        }
                    }
                }
            }
            return false;
        } else {
            return true;
        }
        
    }
    private Boolean isNestedWithinUIData() {
        if ( == null) {
            UIComponent parent = this;
            while (null != (parent = parent.getParent())) {
                if (parent instanceof UIData) {
                     = .;
                    break;
                }
            }
            if ( == null) {
                 = .;
            }
            return ;
        } else {
            return ;
        }
    }


    

Restore state information for all descendant components, as described for setRowIndex().

    private void restoreDescendantState() {
        FacesContext context = getFacesContext();
        if (getChildCount() > 0) {
            for (UIComponent kid : getChildren()) {
                if (kid instanceof UIColumn) {
                    restoreDescendantState(kidcontext);
                }
            }
        }
    }


    

Restore state information for the specified component and its descendants.

Parameters:
component Component for which to restore state information
context FacesContext for the current request
    private void restoreDescendantState(UIComponent component,
                                        FacesContext context) {
        // Reset the client identifier for this component
        String id = component.getId();
        component.setId(id); // Forces client id to be reset
        // Restore state for this component (if it is a EditableValueHolder)
        if (component instanceof EditableValueHolder) {
            EditableValueHolder input = (EditableValueHoldercomponent;
            String clientId = component.getClientId(context);
            SavedState state = .get(clientId);
            if (state == null) {
                state = new SavedState();
            }
            input.setValue(state.getValue());
            input.setValid(state.isValid());
            input.setSubmittedValue(state.getSubmittedValue());
            // This *must* be set after the call to setValue(), since
            // calling setValue() always resets "localValueSet" to true.
            input.setLocalValueSet(state.isLocalValueSet());
        }
        // Restore state for children of this component
        if (component.getChildCount() > 0) {
            for (UIComponent kid : component.getChildren()) {
                restoreDescendantState(kidcontext);
            }
        }
        // Restore state for facets of this component
        if (component.getFacetCount() > 0) {
            for (UIComponent facet : component.getFacets().values()) {
                restoreDescendantState(facetcontext);
            }
        }
    }


    

Save state information for all descendant components, as described for setRowIndex().

    private void saveDescendantState() {
        FacesContext context = getFacesContext();
        if (getChildCount() > 0) {
            for (UIComponent kid : getChildren()) {
                if (kid instanceof UIColumn) {
                    saveDescendantState(kidcontext);
                }
            }
        }
    }


    

Save state information for the specified component and its descendants.

Parameters:
component Component for which to save state information
context FacesContext for the current request
    private void saveDescendantState(UIComponent component,
                                     FacesContext context) {
        // Save state for this component (if it is a EditableValueHolder)
        if (component instanceof EditableValueHolder) {
            EditableValueHolder input = (EditableValueHoldercomponent;
            String clientId = component.getClientId(context);
            SavedState state = .get(clientId);
            if (state == null) {
                state = new SavedState();
                .put(clientIdstate);
            }
            state.setValue(input.getLocalValue());
            state.setValid(input.isValid());
            state.setSubmittedValue(input.getSubmittedValue());
            state.setLocalValueSet(input.isLocalValueSet());
        }
        // Save state for children of this component
        if (component.getChildCount() > 0) {
            for (UIComponent uiComponent : component.getChildren()) {
                saveDescendantState(uiComponentcontext);
            }
        }
        // Save state for facets of this component
        if (component.getFacetCount() > 0) {
            for (UIComponent facet : component.getFacets().values()) {
                saveDescendantState(facetcontext);
            }
        }
    }
// ------------------------------------------------------------- Private Classes
// Private class to represent saved state information
@SuppressWarnings({"SerializableHasSerializationMethods",
      "NonSerializableFieldInSerializableClass"})
class SavedState implements Serializable {
    private static final long serialVersionUID = 2920252657338389849L;
    private Object submittedValue;
        return (this.);
    }
    void setSubmittedValue(Object submittedValue) {
        this. = submittedValue;
    }
    private boolean valid = true;
    boolean isValid() {
        return (this.);
    }
    void setValid(boolean valid) {
        this. = valid;
    }
    private Object value;
    Object getValue() {
        return (this.);
    }
    public void setValue(Object value) {
        this. = value;
    }
    private boolean localValueSet;
    boolean isLocalValueSet() {
        return (this.);
    }
    public void setLocalValueSet(boolean localValueSet) {
        this. = localValueSet;
    }
    public String toString() {
        return ("submittedValue: " +  +
                " value: " +  +
                " localValueSet: " + );
    }
// Private class to wrap an event with a row index
class WrapperEvent extends FacesEvent {
    public WrapperEvent(UIComponent componentFacesEvent eventint rowIndex) {
        super(component);
        this. = event;
        this. = rowIndex;
    }
    private FacesEvent event = null;
    private int rowIndex = -1;
    public FacesEvent getFacesEvent() {
        return (this.);
    }
    public int getRowIndex() {
        return (this.);
    }
    public PhaseId getPhaseId() {
        return (this..getPhaseId());
    }
    public void setPhaseId(PhaseId phaseId) {
        this..setPhaseId(phaseId);
    }
    public boolean isAppropriateListener(FacesListener listener) {
        return (false);
    }
    public void processListener(FacesListener listener) {
        throw new IllegalStateException();
    }