001: /*
002: * Copyright 2004,2005,2006 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package javax.faces.model;
017:
018: import java.util.ArrayList;
019: import java.util.List;
020:
021: /**
022: * Represents the data presented by a UIData component, together with
023: * some state information about the currently selected row within the
024: * datalist for use by listeners on UIData components. This class allows
025: * managed bean code to avoid binding directly to UIData components for
026: * typical uses.
027: * <p>
028: * Note that DataModel and its standard subclasses are not serializable,
029: * as there is no state in a DataModel object itself that needs to be
030: * preserved between render and restore-view. UIData components therefore
031: * do not store their DataModel when serialized; they just evaluate their
032: * "value" EL expression to refetch the object during the
033: * apply-request-values phase.
034: * <p>
035: * Because DataModel is not serializable, any managed bean that needs to
036: * be serialized and which has a member of type DataModel should therefore
037: * mark that member transient. If there is a need to preserve the datalist
038: * contained within the DataModel then ensure a reference to that list is
039: * stored in a non-transient member, or use a custom serialization method
040: * that explicitly serializes dataModel.getWrappedData.
041: *
042: * See Javadoc of <a href="http://java.sun.com/javaee/javaserverfaces/1.2/docs/api/index.html">JSF Specification</a> for more.
043: *
044: * @author Thomas Spiegl (latest modification by $Author: mbr $)
045: * @version $Revision: 512227 $ $Date: 2007-02-27 13:25:16 +0100 (Di, 27 Feb 2007) $
046: */
047: public abstract class DataModel {
048: // FIELDS
049: private List<DataModelListener> _listeners;
050:
051: // METHODS
052: public void addDataModelListener(DataModelListener listener) {
053: if (listener == null)
054: throw new NullPointerException("listener");
055: if (_listeners == null) {
056: _listeners = new ArrayList<DataModelListener>();
057: }
058: _listeners.add(listener);
059: }
060:
061: public DataModelListener[] getDataModelListeners() {
062: if (_listeners == null) {
063: return new DataModelListener[0];
064: }
065: return _listeners.toArray(new DataModelListener[_listeners
066: .size()]);
067: }
068:
069: /**
070: * Return the number of rows of data available.
071: * <p>
072: * If the number of rows of data available is not known then -1 is returned.
073: * This may happen for DataModels that wrap sources of data such as
074: * java.sql.ResultSet that provide an iterator to access the "next item"
075: * rather than a fixed-size collection of data.
076: */
077: abstract public int getRowCount();
078:
079: /**
080: * Return the object associated with the current row index.
081: * <p>
082: * Method isRowAvailable may be called before attempting to access
083: * this method, to ensure that the data is available.
084: *
085: * @throws RuntimeException subclass of some kind if the current row index
086: * is not within the range of the current wrappedData property.
087: */
088: abstract public Object getRowData();
089:
090: /**
091: * Get the current row index.
092: */
093: abstract public int getRowIndex();
094:
095: /**
096: * Get the entire collection of data associated with this component. Note that
097: * the actual type of the returned object depends upon the concrete
098: * subclass of DataModel; the object will represent an "ordered sequence
099: * of components", but may be implemented as an array, java.util.List,
100: * java.sql.ResultSet or other similar types.
101: */
102: abstract public Object getWrappedData();
103:
104: /**
105: * Returns true if a call to getRowData will return a valid object.
106: */
107: abstract public boolean isRowAvailable();
108:
109: public void removeDataModelListener(DataModelListener listener) {
110: if (listener == null)
111: throw new NullPointerException("listener");
112: if (_listeners != null) {
113: _listeners.remove(listener);
114: }
115: }
116:
117: /**
118: * Set the current row index. This affects the behaviour of the
119: * getRowData method in particular.
120: *
121: * Parameter rowIndex may be -1 to indicate "no row", or may be a value
122: * between 0 and getRowCount()-1.
123: */
124: abstract public void setRowIndex(int rowIndex);
125:
126: /**
127: * Set the entire list of data associated with this component. Note that
128: * the actual type of the provided object must match the expectations
129: * of the concrete subclass of DataModel. See getWrappedData.
130: */
131: abstract public void setWrappedData(Object data);
132: }
|