View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package javax.faces.model;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  /**
25    * Represents the data presented by a UIData component, together with
26    * some state information about the currently selected row within the
27    * datalist for use by listeners on UIData components. This class allows
28    * managed bean code to avoid binding directly to UIData components for
29    * typical uses.
30    * <p> 
31    * Note that DataModel and its standard subclasses are not serializable,
32    * as there is no state in a DataModel object itself that needs to be
33    * preserved between render and restore-view. UIData components therefore
34    * do not store their DataModel when serialized; they just evaluate their
35    * "value" EL expression to refetch the object during the 
36    * apply-request-values phase.
37    * <p>
38    * Because DataModel is not serializable, any managed bean that needs to
39    * be serialized and which has a member of type DataModel should therefore
40    * mark that member transient. If there is a need to preserve the datalist
41    * contained within the DataModel then ensure a reference to that list is
42    * stored in a non-transient member, or use a custom serialization method
43    * that explicitly serializes dataModel.getWrappedData.
44    *  
45    * See Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for more.
46    * 
47    * @author Thomas Spiegl (latest modification by $Author: lu4242 $)
48    * @version $Revision: 1203272 $ $Date: 2011-11-17 12:06:55 -0500 (Thu, 17 Nov 2011) $
49  */
50  public abstract class DataModel
51  {
52      private final static DataModelListener[] EMPTY_DATA_MODEL_LISTENER = new DataModelListener[]{};
53      // FIELDS
54      private List<DataModelListener> _listeners;
55      
56      private DataModelListener[] _cachedListenersArray = null;
57  
58      // METHODS
59      public void addDataModelListener(DataModelListener listener)
60      {
61          if (listener == null) throw new NullPointerException("listener");
62          if (_listeners == null)
63          {
64              _listeners = new ArrayList<DataModelListener>();
65          }
66          _listeners.add(listener);
67          _cachedListenersArray = null;
68      }
69  
70      public DataModelListener[] getDataModelListeners()
71      {
72          if (_listeners == null)
73          {
74              return EMPTY_DATA_MODEL_LISTENER;
75          }
76          if (_cachedListenersArray == null)
77          {
78              _cachedListenersArray = _listeners.toArray(new DataModelListener[_listeners.size()]);
79          }
80          return _cachedListenersArray;
81      }
82  
83      /**
84       * <p>
85       * Return the number of rows of data available. 
86       * </p>
87       * <p>
88       * If the number of rows of data available is not known then -1 is returned.
89       * This may happen for DataModels that wrap sources of data such as 
90       * java.sql.ResultSet that provide an iterator to access the "next item"
91       * rather than a fixed-size collection of data.
92       * </p>
93       *
94       * @return the number of rows available.
95       */
96      abstract public int getRowCount();
97  
98      /**
99       * Return the object associated with the current row index.
100      * <p>
101      * Method isRowAvailable may be called before attempting to access
102      * this method, to ensure that the data is available.
103      *
104      * @return The object associated with the current row index.
105      * @throws RuntimeException subclass of some kind if the current row index
106      * is not within the range of the current wrappedData property.
107      */
108     abstract public Object getRowData();
109 
110     /**
111      * Get the current row index.
112      * @return The current row index.
113      */
114     abstract public int getRowIndex();
115 
116     /**
117      * Get the entire collection of data associated with this component. Note that
118      * the actual type of the returned object depends upon the concrete
119      * subclass of DataModel; the object will represent an "ordered sequence
120      * of components", but may be implemented as an array, java.util.List,
121      * java.sql.ResultSet or other similar types.
122      *
123      * @return the wrapped object.
124      */
125     abstract public Object getWrappedData();
126 
127     /**
128      * Returns true if a call to getRowData will return a valid object.
129      * @return true if a call to getRowData will return a valid object. false otherwise.
130      */
131     abstract public boolean isRowAvailable();
132 
133     public void removeDataModelListener(DataModelListener listener)
134     {
135         if (listener == null) throw new NullPointerException("listener");
136         if (_listeners != null)
137         {
138             _listeners.remove(listener);
139         }
140         _cachedListenersArray = null;
141     }
142 
143     /**
144      * Set the current row index. This affects the behaviour of the
145      * getRowData method in particular.
146      * 
147      * @param rowIndex The row index. It may be -1 to indicate "no row",
148      *                 or may be a value between 0 and getRowCount()-1. 
149      */
150     abstract public void setRowIndex(int rowIndex);
151 
152     /**
153      * Set the entire list of data associated with this component. Note that
154      * the actual type of the provided object must match the expectations
155      * of the concrete subclass of DataModel. See getWrappedData.
156      *
157      * @param data The object to be wrapped.
158      */
159     abstract public void setWrappedData(Object data);
160 }