package org.ovirt.engine.ui.common.widget.refresh;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.ovirt.engine.ui.common.system.ApplicationFocusChangeEvent;
import org.ovirt.engine.ui.common.system.ClientStorage;
import org.ovirt.engine.ui.common.uicommon.model.ModelProvider;
import org.ovirt.engine.ui.uicommonweb.models.GridController;
import org.ovirt.engine.ui.uicommonweb.models.GridTimer;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.HasHandlers;
/**
* Provides refresh rate management for a {@link GridController}.
*/
public abstract class AbstractRefreshManager<T extends BaseRefreshPanel> implements HasHandlers {
/**
* Callback triggered when the user clicks the refresh button.
*/
public interface ManualRefreshCallback {
void onManualRefresh();
}
// Key used to store refresh rate of all data grids
private static final String GRID_REFRESH_RATE_KEY = "GridRefreshRate"; //$NON-NLS-1$
private static final Integer DEFAULT_REFRESH_RATE = GridTimer.DEFAULT_NORMAL_RATE;
private static final Integer OUT_OF_FOCUS_REFRESH_RATE = Integer.valueOf(60000);
private static final Set<Integer> REFRESH_RATES = new LinkedHashSet<>();
static {
REFRESH_RATES.add(DEFAULT_REFRESH_RATE);
REFRESH_RATES.add(10000);
REFRESH_RATES.add(20000);
REFRESH_RATES.add(30000);
REFRESH_RATES.add(OUT_OF_FOCUS_REFRESH_RATE);
}
/**
* Returns acceptable refresh rates.
*/
public static Set<Integer> getRefreshRates() {
return Collections.unmodifiableSet(REFRESH_RATES);
}
private final ModelProvider<? extends GridController> modelProvider;
private final ClientStorage clientStorage;
private final T refreshPanel;
private final EventBus eventBus;
private ManualRefreshCallback manualRefreshCallback;
private HandlerRegistration statusUpdateHandlerRegistration;
public AbstractRefreshManager(ModelProvider<? extends GridController> modelProvider,
EventBus eventBus, ClientStorage clientStorage) {
this.modelProvider = modelProvider;
this.clientStorage = clientStorage;
this.eventBus = eventBus;
this.refreshPanel = createRefreshPanel();
listenOnManualRefresh();
updateController();
// Add handler to be notified when the application window gains or looses its focus
eventBus.addHandler(ApplicationFocusChangeEvent.getType(), event -> onWindowFocusChange(event.isInFocus()));
}
private void updateController() {
updateTimer();
}
private void updateTimer() {
final GridTimer modelTimer = getModelTimer();
modelTimer.setRefreshRate(readRefreshRate());
if (statusUpdateHandlerRegistration != null) {
statusUpdateHandlerRegistration.removeHandler();
}
statusUpdateHandlerRegistration = modelTimer.addGridTimerStateChangeEventHandler(event -> onRefresh(modelTimer.getTimerRefreshStatus()));
modelTimer.resume();
}
/**
* Returns the refresh timer used by the {@link GridController}.
*/
GridTimer getModelTimer() {
return modelProvider.getModel().getTimer();
}
/**
* Callback fired when the application window gains or looses its focus.
*/
void onWindowFocusChange(boolean inFocus) {
GridTimer modelTimer = getModelTimer();
// Change refresh rate only when the model timer is currently active and not paused
if (modelTimer.isActive() && !modelTimer.isPaused()) {
modelTimer.stop();
if (inFocus) {
modelTimer.setRefreshRate(readRefreshRate());
} else {
modelTimer.setRefreshRate(OUT_OF_FOCUS_REFRESH_RATE);
}
modelTimer.start();
}
}
/**
* When the user clicks the refresh button, enforce the refresh without even asking the timer.
*/
protected void listenOnManualRefresh() {
refreshPanel.addClickHandler(event -> {
if (manualRefreshCallback != null) {
manualRefreshCallback.onManualRefresh();
}
ManualRefreshEvent.fire(AbstractRefreshManager.this);
modelProvider.getModel().refresh();
});
}
protected abstract T createRefreshPanel();
protected void onRefresh(String status) {
refreshPanel.setTooltipText(status);
}
public T getRefreshPanel() {
return refreshPanel;
}
public void setCurrentRefreshRate(int newRefreshRate) {
saveRefreshRate(newRefreshRate);
updateTimer();
}
public int getCurrentRefreshRate() {
return getModelTimer().getRefreshRate();
}
String getRefreshRateItemKey() {
return GRID_REFRESH_RATE_KEY;
}
void saveRefreshRate(int newRefreshRate) {
clientStorage.setLocalItem(getRefreshRateItemKey(), String.valueOf(newRefreshRate));
}
/**
* Returns refresh rate value if it exists. Otherwise, returns default refresh rate.
*/
int readRefreshRate() {
String refreshRate = clientStorage.getLocalItem(getRefreshRateItemKey());
try {
return Integer.parseInt(refreshRate);
} catch (NumberFormatException e) {
return getDefaultRefreshRate();
}
}
protected int getDefaultRefreshRate() {
return DEFAULT_REFRESH_RATE;
}
public void setManualRefreshCallback(ManualRefreshCallback manualRefreshCallback) {
this.manualRefreshCallback = manualRefreshCallback;
}
@Override
public void fireEvent(GwtEvent<?> event) {
eventBus.fireEventFromSource(event, modelProvider.getModel());
}
public String getRefreshStatus() {
return getModelTimer().getTimerRefreshStatus();
}
}