package org.ovirt.engine.ui.common.uicommon.model;
import java.util.ArrayList;
import java.util.List;
import org.ovirt.engine.core.common.businessentities.IVdcQueryable;
import org.ovirt.engine.ui.common.presenter.popup.DefaultConfirmationPopupPresenterWidget;
import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel;
import org.ovirt.engine.ui.uicompat.PropertyChangedEventArgs;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.ProvidesKey;
import com.google.inject.Provider;
/**
* A {@link SearchableModelProvider} implementation that provides data to {@link HasData} widgets.
*
* @param <T>
* List model item type.
* @param <M>
* List model type.
*/
public abstract class DataBoundTabModelProvider<T, M extends SearchableListModel> extends TabModelProvider<M> implements SearchableTableModelProvider<T, M> {
private final AsyncDataProvider<T> dataProvider;
public DataBoundTabModelProvider(EventBus eventBus,
Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider) {
this(eventBus, defaultConfirmPopupProvider, null);
}
public DataBoundTabModelProvider(EventBus eventBus,
Provider<DefaultConfirmationPopupPresenterWidget> defaultConfirmPopupProvider,
ProvidesKey<T> keyProvider) {
super(eventBus, defaultConfirmPopupProvider);
this.dataProvider = new AsyncDataProvider<T>(keyProvider) {
@Override
protected void onRangeChanged(HasData<T> display) {
// We might get here after the ItemsChangedEvent has been triggered
updateData();
}
};
}
@Override
protected void initializeModelHandlers(M model) {
super.initializeModelHandlers(model);
// Add model items change handler
model.getItemsChangedEvent().addListener((ev, sender, args) -> {
if (handleItemsChangedEvent()) {
updateData();
}
});
model.getPropertyChangedEvent().addListener((ev, sender, args) -> {
if (PropertyChangedEventArgs.PROGRESS.equals(args.propertyName)) {
clearData();
}
});
}
void clearData() {
getDataProvider().updateRowCount(0, false);
}
/**
* @return {@code true} when the ItemsChangedEvent of the model should trigger data update, {@code false} otherwise.
*/
protected boolean handleItemsChangedEvent() {
return true;
}
@Override
public void setSelectedItems(List<T> items) {
// Order is important
getModel().setSelectedItem(items.size() > 0 ? items.get(0) : null);
getModel().setSelectedItems(items);
}
@Override
public void onManualRefresh() {
//Do nothing by default.
}
@Override
public Object getKey(T item) {
if (item instanceof IVdcQueryable) {
return ((IVdcQueryable) item).getQueryableId();
}
return getDataProvider().getKey(item);
}
@Override
public boolean canGoForward() {
return getModel().getSearchNextPageCommand().getIsExecutionAllowed();
}
@Override
public boolean canGoBack() {
return getModel().getSearchPreviousPageCommand().getIsExecutionAllowed();
}
@Override
public void goForward() {
getModel().getSearchNextPageCommand().execute();
}
@Override
public void goBack() {
getModel().getSearchPreviousPageCommand().execute();
}
@Override
public void refresh() {
getModel().getForceRefreshCommand().execute();
}
@Override
public String getItemsCount() {
return getModel().getItemsCountString();
}
/**
* Retrieves current data from model and updates the data provider.
*/
@SuppressWarnings("unchecked")
protected void updateData() {
List<T> items = getModel().getItems() == null ? null : new ArrayList<T>(getModel().getItems());
if (items != null) {
updateDataProvider(items);
}
}
/**
* Updates the data provider with new data received from model.
*/
protected void updateDataProvider(List<T> items) {
dataProvider.updateRowCount(items.size(), true);
dataProvider.updateRowData(0, items);
}
protected AsyncDataProvider<T> getDataProvider() {
return dataProvider;
}
@Override
public void addDataDisplay(HasData<T> display) {
dataProvider.addDataDisplay(display);
}
}