All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jakarta.faces.model.DataModel Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package jakarta.faces.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import jakarta.faces.component.UIData;

/**
 * 

* DataModel is an abstraction around arbitrary data binding * technologies that can be used to adapt a variety of data sources for use by Jakarta Faces components that * support per-row processing for their child components (such as {@link UIData}. *

* *

* The data collection underlying a {@link DataModel} instance is modeled as a collection of row objects that can be * accessed by a zero-relative cursor (row index). The APIs provide mechanisms to position to a specified zero-relative * row index, and to retrieve an object that represents the data that corresponds to the current row index. *

* *

* A concrete {@link DataModel} instance is attached to a particular collection of underlying data by calling the * setWrappedData() method. It can be detached from that underlying data collection by passing a * null parameter to this method. *

* *

* Concrete {@link DataModel} implementations must provide a public zero-arguments constructor that calls * setWrappedData(null). A convenience constructor that takes a wrapped object of the appropriate type (and * passes it on via a call to setWrappedData(), should also be provided. *

* *

* Event listeners may be registered to receive notifications of when a new row index is selected. *

*/ public abstract class DataModel implements Iterable { private static final DataModelListener[] EMPTY_DATA_MODEL_LISTENER = new DataModelListener[0]; // -------------------------------------------------------------- Properties /** *

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

* * @throws jakarta.faces.FacesException if an error occurs getting the row availability * * @return true if and only if there is data available at the current index, false otherwise. */ public abstract boolean isRowAvailable(); /** *

* Return the number of rows of data objects represented by this {@link DataModel}. If the number of rows is unknown, or * no wrappedData is available, return -1. *

* * @throws jakarta.faces.FacesException if an error occurs getting the row count * * @return the number of rows of data represented by this {@code DataModel} */ public abstract int getRowCount(); /** *

* Return an object representing the data for the currently selected row index. If no wrappedData is * available, return null. *

* * @throws jakarta.faces.FacesException if an error occurs getting the row data * @throws IllegalArgumentException if now row data is available at the currently specified row index * * @return an object representing the data for the currently selected row index */ public abstract E getRowData(); /** *

* Return the zero-relative index of the currently selected row. If we are not currently positioned on a row, or no * wrappedData is available, return -1. *

* * @throws jakarta.faces.FacesException if an error occurs getting the row index * * @return the index of the currently selected row */ public abstract int getRowIndex(); /** *

* Set the zero-relative index of the currently selected row, or -1 to indicate that we are not positioned on a row. 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. *

* *

* If there is no wrappedData available when this method is called, the specified rowIndex is * stored (and may be retrieved by a subsequent call to getRowData()), but no event is sent. Otherwise, if * the currently selected row index is changed by this call, a {@link DataModelEvent} will be sent to the * rowSelected() method of all registered {@link DataModelListener}s. *

* * @param rowIndex The new zero-relative index (must be non-negative) * * @throws jakarta.faces.FacesException if an error occurs setting the row index * @throws IllegalArgumentException if rowIndex is less than -1 */ public abstract void setRowIndex(int rowIndex); /** *

* Return the object representing the data wrapped by this {@link DataModel}, if any. *

* * @return the {@code Object} that this model wraps. */ public abstract Object getWrappedData(); /** *

* Set the object representing the data collection wrapped by this {@link DataModel}. If the specified data * is null, detach this {@link DataModel} from any previously wrapped data collection instead. *

* *

* If data is non-null, the currently selected row index must be set to zero, and a * {@link DataModelEvent} must be sent to the rowSelected() method of all registered * {@link DataModelListener}s indicating that this row is now selected. *

* * @param data Data collection to be wrapped, or null to detach from any previous data collection * * @throws ClassCastException if data is not of the appropriate type for this {@link DataModel} * implementation */ public abstract void setWrappedData(Object data); // ------------------------------------------------------ Instance Variables /** *

* The list of registered {@link DataModelListener}s for this {@link DataModel}. This variable will be null * unless there is at least one registered listener. *

*/ private List listeners = null; // --------------------------------------------- Event Listener Registration /** *

* Add a new {@link DataModelListener} to the set interested in notifications from this {@link DataModel}. *

* * @param listener The new {@link DataModelListener} to be registered * * @throws NullPointerException if listener is null */ public void addDataModelListener(DataModelListener listener) { if (listener == null) { throw new NullPointerException(); } if (listeners == null) { // noinspection CollectionWithoutInitialCapacity listeners = new ArrayList<>(); } listeners.add(listener); } /** *

* Return the set of {@link DataModelListener}s interested in notifications from this {@link DataModel}. If there are no * such listeners, an empty array is returned. *

* * @return the listeners for this instance, or an empty array */ public DataModelListener[] getDataModelListeners() { if (listeners == null) { return EMPTY_DATA_MODEL_LISTENER; } else { return listeners.toArray(new DataModelListener[listeners.size()]); } } /** *

* Remove an existing {@link DataModelListener} from the set interested in notifications from this {@link DataModel}. *

* * @param listener The old {@link DataModelListener} to be deregistered * * @throws NullPointerException if listener is null */ public void removeDataModelListener(DataModelListener listener) { if (listener == null) { throw new NullPointerException(); } if (listeners != null) { listeners.remove(listener); if (listeners.isEmpty()) { listeners = null; } } } /** *

* Return a read-only Iterator over the row data for this model. *

* * @since 2.0 */ @Override public Iterator iterator() { return new DataModelIterator<>(this); } // ---------------------------------------------------------- Nested Classes @SuppressWarnings({ "unchecked" }) private static final class DataModelIterator implements Iterator { private final DataModel model; private int index; // -------------------------------------------------------- Constructors DataModelIterator(DataModel model) { this.model = model; this.model.setRowIndex(index); } // ----------------------------------------------- Methods from Iterator /** * @see java.util.Iterator#hasNext() */ @Override public boolean hasNext() { return model.isRowAvailable(); } /** * @see java.util.Iterator#next() */ @Override public T next() { if (!model.isRowAvailable()) { throw new NoSuchElementException(); } Object o = model.getRowData(); model.setRowIndex(++index); return (T) o; } /** * Unsupported. * * @see java.util.Iterator#remove() */ @Override public void remove() { throw new UnsupportedOperationException(); } } // END DataModelIterator }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy