package org.ovirt.engine.ui.webadmin.section.main.view.popup.quota;
import java.util.ArrayList;
import org.ovirt.engine.core.common.businessentities.QuotaCluster;
import org.ovirt.engine.core.common.businessentities.QuotaStorage;
import org.ovirt.engine.core.common.businessentities.StoragePool;
import org.ovirt.engine.core.common.utils.SizeConverter;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
import org.ovirt.engine.ui.common.idhandler.ElementIdHandler;
import org.ovirt.engine.ui.common.idhandler.WithElementId;
import org.ovirt.engine.ui.common.view.popup.AbstractModelBoundPopupView;
import org.ovirt.engine.ui.common.widget.Align;
import org.ovirt.engine.ui.common.widget.dialog.SimpleDialogPanel;
import org.ovirt.engine.ui.common.widget.editor.ListModelListBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.ListModelObjectCellTable;
import org.ovirt.engine.ui.common.widget.editor.generic.EntityModelCheckBoxEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.EntityModelRadioButtonEditor;
import org.ovirt.engine.ui.common.widget.editor.generic.StringEntityModelTextBoxEditor;
import org.ovirt.engine.ui.common.widget.form.Slider;
import org.ovirt.engine.ui.common.widget.form.Slider.SliderValueChange;
import org.ovirt.engine.ui.common.widget.renderer.DiskSizeRenderer;
import org.ovirt.engine.ui.common.widget.renderer.NameRenderer;
import org.ovirt.engine.ui.common.widget.table.cell.CheckboxCell;
import org.ovirt.engine.ui.common.widget.table.column.AbstractTextColumn;
import org.ovirt.engine.ui.uicommonweb.models.ListModel;
import org.ovirt.engine.ui.uicommonweb.models.quota.QuotaModel;
import org.ovirt.engine.ui.uicompat.Event;
import org.ovirt.engine.ui.uicompat.EventArgs;
import org.ovirt.engine.ui.uicompat.IEventListener;
import org.ovirt.engine.ui.webadmin.ApplicationConstants;
import org.ovirt.engine.ui.webadmin.ApplicationMessages;
import org.ovirt.engine.ui.webadmin.gin.AssetProvider;
import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.quota.QuotaPopupPresenterWidget;
import org.ovirt.engine.ui.webadmin.widget.table.cell.NullableButtonCell;
import org.ovirt.engine.ui.webadmin.widget.table.column.QuotaUtilizationStatusColumn;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.inject.Inject;
public class QuotaPopupView extends AbstractModelBoundPopupView<QuotaModel> implements QuotaPopupPresenterWidget.ViewDef, SliderValueChange {
private static final String GRACE_CLUSTER = "GRACE_CLUSTER"; //$NON-NLS-1$
private static final String THRESHOLD_CLUSTER = "THRESHOLD_CLUSTER"; //$NON-NLS-1$
private static final String GRACE_STORAGE = "GRACE_STORAGE"; //$NON-NLS-1$
private static final String THRESHOLD_STORAGE = "THRESHOLD_STORAGE"; //$NON-NLS-1$
private static final String MAX_COLOR = "#4E9FDD"; //$NON-NLS-1$
private static final String MIN_COLOR = "#AFBF27"; //$NON-NLS-1$
private static final DiskSizeRenderer<Number> diskSizeRenderer =
new DiskSizeRenderer<>(SizeConverter.SizeUnit.GiB);
@UiField
WidgetStyle style;
@UiField
@Path(value = "name.entity")
@WithElementId
StringEntityModelTextBoxEditor nameEditor;
@UiField
@Path(value = "description.entity")
@WithElementId
StringEntityModelTextBoxEditor descriptionEditor;
@UiField(provided = true)
@Path(value = "dataCenter.selectedItem")
@WithElementId
ListModelListBoxEditor<StoragePool> dataCenterEditor;
@UiField(provided = true)
@Path(value = "copyPermissions.entity")
@WithElementId("copyPermissions")
EntityModelCheckBoxEditor copyPermissionsEditor;
@UiField
@Ignore
Label memAndCpuLabel;
@UiField
@Ignore
Label storageLabel;
@UiField(provided = true)
Slider clusterGraceSlider;
@UiField(provided = true)
Slider clusterThresholdSlider;
@UiField
@Ignore
Label clusterThresholdLabel;
@UiField
@Ignore
Label clusterGraceLabel;
@UiField(provided = true)
Slider storageGraceSlider;
@UiField(provided = true)
Slider storageThresholdSlider;
@UiField
@Ignore
Label storageThresholdLabel;
@UiField
@Ignore
Label storageGraceLabel;
@UiField(provided = true)
@Path(value = "globalClusterQuota.entity")
@WithElementId
EntityModelRadioButtonEditor globalClusterQuotaRadioButtonEditor;
@UiField(provided = true)
@Path(value = "specificClusterQuota.entity")
@WithElementId
EntityModelRadioButtonEditor specificClusterQuotaRadioButtonEditor;
@UiField(provided = true)
@Path(value = "globalStorageQuota.entity")
@WithElementId
EntityModelRadioButtonEditor globalStorageQuotaRadioButtonEditor;
@UiField(provided = true)
@Path(value = "specificStorageQuota.entity")
@WithElementId
EntityModelRadioButtonEditor specificStorageQuotaRadioButtonEditor;
@UiField
@Ignore
ScrollPanel clusterQuotaTableContainer;
@Ignore
ListModelObjectCellTable<QuotaCluster, ListModel> quotaClusterTable;
@Ignore
ListModelObjectCellTable<QuotaStorage, ListModel> quotaStorageTable;
@UiField
@Ignore
ScrollPanel storageQuotaTableContainer;
private Column<QuotaCluster, Boolean> isClusterInQuotaColumn = null;
private Column<QuotaStorage, Boolean> isStorageInQuotaColumn = null;
private QuotaModel model;
private boolean firstTime = false;
ArrayList<Guid> selectedClusterGuid = new ArrayList<>();
ArrayList<Guid> selectedStorageGuid = new ArrayList<>();
interface Driver extends UiCommonEditorDriver<QuotaModel, QuotaPopupView> {
}
interface ViewUiBinder extends UiBinder<SimpleDialogPanel, QuotaPopupView> {
ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
}
interface ViewIdHandler extends ElementIdHandler<QuotaPopupView> {
ViewIdHandler idHandler = GWT.create(ViewIdHandler.class);
}
private final Driver driver = GWT.create(Driver.class);
private static final ApplicationConstants constants = AssetProvider.getConstants();
private static final ApplicationMessages messages = AssetProvider.getMessages();
@Inject
public QuotaPopupView(EventBus eventBus) {
super(eventBus);
initListBoxEditors();
initRadioButtonEditors();
initCheckBoxes();
initSliders();
initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
ViewIdHandler.idHandler.generateAndSetIds(this);
localize();
addStyles();
driver.initialize(this);
initTables();
}
private void initCheckBoxes() {
copyPermissionsEditor = new EntityModelCheckBoxEditor(Align.RIGHT);
}
private void addStyles() {
copyPermissionsEditor.addContentWidgetContainerStyleName(style.textBoxWidth());
}
private void initSliders() {
clusterThresholdSlider = new Slider(2, 1, 100, 80, MIN_COLOR);
clusterThresholdSlider.setSliderValueChange(THRESHOLD_CLUSTER, this);
clusterGraceSlider = new Slider(2, 101, 200, 120, MAX_COLOR);
clusterGraceSlider.setSliderValueChange(GRACE_CLUSTER, this);
storageThresholdSlider = new Slider(2, 1, 100, 80, MIN_COLOR);
storageThresholdSlider.setSliderValueChange(THRESHOLD_STORAGE, this);
storageGraceSlider = new Slider(2, 101, 200, 120, MAX_COLOR);
storageGraceSlider.setSliderValueChange(GRACE_STORAGE, this);
}
private void initTables() {
initQuotaClusterTable();
initQuotaStorageTable();
}
private void initQuotaStorageTable() {
quotaStorageTable = new ListModelObjectCellTable<>();
storageQuotaTableContainer.add(quotaStorageTable);
isStorageInQuotaColumn = new Column<QuotaStorage, Boolean>(
new CheckboxCell(true, true)) {
@Override
public Boolean getValue(QuotaStorage object) {
if (selectedStorageGuid.contains(object.getStorageId()) || object.getStorageSizeGB() != null) {
if (!selectedStorageGuid.contains(object.getStorageId())) {
selectedStorageGuid.add(object.getStorageId());
}
return true;
}
return false;
}
};
isStorageInQuotaColumn.setFieldUpdater((index, object, value) -> {
if (value) {
selectedStorageGuid.add(object.getStorageId());
object.setStorageSizeGB(QuotaStorage.UNLIMITED);
} else {
selectedStorageGuid.remove(object.getStorageId());
object.setStorageSizeGB(null);
}
if (model.getGlobalStorageQuota().getEntity()) {
quotaStorageTable.asEditor().edit(model.getQuotaStorages());
} else {
quotaStorageTable.asEditor().edit(model.getAllDataCenterStorages());
}
});
quotaStorageTable.addColumn(new AbstractTextColumn<QuotaStorage>() {
@Override
public String getValue(QuotaStorage object) {
if (object.getStorageName() == null || object.getStorageName().length() == 0) {
return constants.utlQuotaAllStoragesQuotaPopup(); //$NON-NLS-1$
}
return object.getStorageName();
}
}, constants.storageNameQuota(), "200px"); //$NON-NLS-1$
quotaStorageTable.addColumn(new QuotaUtilizationStatusColumn<QuotaStorage>(), constants.empty(), "1px"); //$NON-NLS-1$
quotaStorageTable.addColumn(new AbstractTextColumn<QuotaStorage>() {
@Override
public String getValue(QuotaStorage object) {
if (object.getStorageSizeGB() == null) {
return ""; //$NON-NLS-1$
} else if (object.getStorageSizeGB().equals(QuotaStorage.UNLIMITED)) {
return messages.unlimitedStorageConsumption(object.getStorageSizeGBUsage() == 0 ?
"0" : //$NON-NLS-1$
diskSizeRenderer.render(object.getStorageSizeGBUsage()));
} else {
return messages.limitedStorageConsumption(object.getStorageSizeGBUsage() == 0 ?
"0" : //$NON-NLS-1$
diskSizeRenderer.render(object.getStorageSizeGBUsage())
, object.getStorageSizeGB());
}
}
}, constants.quota());
NullableButtonCell editCellButton = new NullableButtonCell();
Column<QuotaStorage, String> editColumn = new Column<QuotaStorage, String>(editCellButton) {
@Override
public String getValue(QuotaStorage object) {
if (model.getGlobalStorageQuota().getEntity()
|| (model.getSpecificStorageQuota().getEntity() && selectedStorageGuid.contains(object.getStorageId()))) {
return constants.editCellQuota();
}
return null;
}
};
quotaStorageTable.addColumn(editColumn, constants.empty(), "50px"); //$NON-NLS-1$
editColumn.setFieldUpdater((index, object, value) -> model.editQuotaStorage(object));
}
private void initQuotaClusterTable() {
quotaClusterTable = new ListModelObjectCellTable<>();
clusterQuotaTableContainer.add(quotaClusterTable);
isClusterInQuotaColumn = new Column<QuotaCluster, Boolean>(
new CheckboxCell(true, true)) {
@Override
public Boolean getValue(QuotaCluster object) {
if (selectedClusterGuid.contains(object.getClusterId())
|| (object.getMemSizeMB() != null && object.getVirtualCpu() != null)) {
if (!selectedClusterGuid.contains(object.getClusterId())) {
selectedClusterGuid.add(object.getClusterId());
}
return true;
}
return false;
}
};
isClusterInQuotaColumn.setFieldUpdater((index, object, value) -> {
if (value) {
selectedClusterGuid.add(object.getClusterId());
object.setVirtualCpu(QuotaCluster.UNLIMITED_VCPU);
object.setMemSizeMB(QuotaCluster.UNLIMITED_MEM);
} else {
selectedClusterGuid.remove(object.getClusterId());
object.setVirtualCpu(null);
object.setMemSizeMB(null);
}
if (model.getGlobalClusterQuota().getEntity()) {
quotaClusterTable.asEditor().edit(model.getQuotaClusters());
} else {
quotaClusterTable.asEditor().edit(model.getAllDataCenterClusters());
}
});
quotaClusterTable.addColumn(new AbstractTextColumn<QuotaCluster>() {
@Override
public String getValue(QuotaCluster object) {
if (object.getClusterName() == null || object.getClusterName().length() == 0) {
return constants.ultQuotaForAllClustersQuotaPopup(); //$NON-NLS-1$
}
return object.getClusterName();
}
}, constants.clusterNameQuota(), "200px"); //$NON-NLS-1$
quotaClusterTable.addColumn(new QuotaUtilizationStatusColumn<QuotaCluster>(), constants.empty(), "1px"); //$NON-NLS-1$
quotaClusterTable.addColumn(new AbstractTextColumn<QuotaCluster>() {
@Override
public String getValue(QuotaCluster object) {
if (object.getMemSizeMB() == null) {
return ""; //$NON-NLS-1$
} else if (object.getMemSizeMB().equals(QuotaCluster.UNLIMITED_MEM)) {
return messages.unlimitedMemConsumption(object.getMemSizeMBUsage());
} else {
return messages.limitedMemConsumption(object.getMemSizeMBUsage(), object.getMemSizeMB());
}
}
}, constants.quotaOfMemQuota());
quotaClusterTable.addColumn(new AbstractTextColumn<QuotaCluster>() {
@Override
public String getValue(QuotaCluster object) {
if (object.getVirtualCpu() == null) {
return ""; //$NON-NLS-1$
} else if (object.getVirtualCpu().equals(QuotaCluster.UNLIMITED_VCPU)) {
return messages.unlimitedVcpuConsumption(object.getVirtualCpuUsage());
} else {
return messages.limitedVcpuConsumption(object.getVirtualCpuUsage(), object.getVirtualCpu());
}
}
}, constants.quotaOfVcpuQuota());
NullableButtonCell editCellButton = new NullableButtonCell();
Column<QuotaCluster, String> editColumn = new Column<QuotaCluster, String>(editCellButton) {
@Override
public String getValue(QuotaCluster object) {
if (model.getGlobalClusterQuota().getEntity()
|| (model.getSpecificClusterQuota().getEntity() && selectedClusterGuid.contains(object.getClusterId()))) {
return constants.editCellQuota();
}
return null;
}
};
quotaClusterTable.addColumn(editColumn, constants.empty(), "50px"); //$NON-NLS-1$
editColumn.setFieldUpdater((index, object, value) -> model.editQuotaCluster(object));
}
private void initRadioButtonEditors() {
globalClusterQuotaRadioButtonEditor = new EntityModelRadioButtonEditor("1"); //$NON-NLS-1$
specificClusterQuotaRadioButtonEditor = new EntityModelRadioButtonEditor("1"); //$NON-NLS-1$
globalStorageQuotaRadioButtonEditor = new EntityModelRadioButtonEditor("2"); //$NON-NLS-1$
specificStorageQuotaRadioButtonEditor = new EntityModelRadioButtonEditor("2"); //$NON-NLS-1$
}
private void initListBoxEditors() {
dataCenterEditor = new ListModelListBoxEditor<>(new NameRenderer<StoragePool>());
}
void localize() {
nameEditor.setLabel(constants.nameQuotaPopup());
descriptionEditor.setLabel(constants.descriptionQuotaPopup());
dataCenterEditor.setLabel(constants.dataCenterQuotaPopup());
copyPermissionsEditor.setLabel(constants.copyQuotaPermissionsQuotaPopup());
memAndCpuLabel.setText(constants.memAndCpuQuotaPopup());
storageLabel.setText(constants.storageQuotaPopup());
globalClusterQuotaRadioButtonEditor.setLabel(constants.ultQuotaForAllClustersQuotaPopup());
specificClusterQuotaRadioButtonEditor.setLabel(constants.useQuotaSpecificClusterQuotaPopup());
globalStorageQuotaRadioButtonEditor.setLabel(constants.utlQuotaAllStoragesQuotaPopup());
specificStorageQuotaRadioButtonEditor.setLabel(constants.usedQuotaSpecStoragesQuotaPopup());
clusterGraceLabel.setText(constants.quotaClusterGrace());
clusterThresholdLabel.setText(constants.quotaClusterThreshold());
storageGraceLabel.setText(constants.quotaStorageGrace());
storageThresholdLabel.setText(constants.quotaStorageThreshold());
}
@Override
public void edit(QuotaModel object) {
this.model = object;
if (!firstTime) {
registerHandlers();
firstTime = true;
updateSliders();
}
quotaClusterTable.asEditor().edit(object.getQuotaClusters());
quotaStorageTable.asEditor().edit(object.getQuotaStorages());
driver.edit(object);
}
private void registerHandlers() {
model.getPropertyChangedEvent().addListener((ev, sender, args) -> {
String propName = args.propertyName;
if ("Window".equals(propName) && model.getWindow() == null) { //$NON-NLS-1$
if (model.getSpecificClusterQuota().getEntity()) {
quotaClusterTable.asEditor().edit(model.getAllDataCenterClusters());
} else {
quotaClusterTable.asEditor().edit(model.getQuotaClusters());
}
if (model.getSpecificStorageQuota().getEntity()) {
quotaStorageTable.asEditor().edit(model.getAllDataCenterStorages());
} else {
quotaStorageTable.asEditor().edit(model.getQuotaStorages());
}
}
});
model.getSpecificClusterQuota().getEntityChangedEvent().addListener(clusterListener);
model.getSpecificStorageQuota().getEntityChangedEvent().addListener(storageListener);
}
final IEventListener<EventArgs> clusterListener = new IEventListener<EventArgs>() {
@Override
public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) {
if (model.getSpecificClusterQuota().getEntity()) {
quotaClusterTable.insertColumn(0, isClusterInQuotaColumn);
quotaClusterTable.setColumnWidth(isClusterInQuotaColumn, "30px"); //$NON-NLS-1$
quotaClusterTable.asEditor().edit(model.getAllDataCenterClusters());
} else {
quotaClusterTable.removeColumn(isClusterInQuotaColumn);
quotaClusterTable.asEditor().edit(model.getQuotaClusters());
}
}
};
final IEventListener<EventArgs> storageListener = new IEventListener<EventArgs>() {
@Override
public void eventRaised(Event<? extends EventArgs> ev, Object sender, EventArgs args) {
if (model.getSpecificStorageQuota().getEntity()) {
quotaStorageTable.insertColumn(0, isStorageInQuotaColumn);
quotaStorageTable.setColumnWidth(isStorageInQuotaColumn, "30px"); //$NON-NLS-1$
quotaStorageTable.asEditor().edit(model.getAllDataCenterStorages());
} else {
quotaStorageTable.removeColumn(isStorageInQuotaColumn);
quotaStorageTable.asEditor().edit(model.getQuotaStorages());
}
}
};
@Override
public QuotaModel flush() {
quotaClusterTable.flush();
quotaStorageTable.flush();
return driver.flush();
}
@Override
public void cleanup() {
driver.cleanup();
}
interface WidgetStyle extends CssResource {
String textBoxWidth();
}
private void updateSliders() {
clusterThresholdSlider.setValue(model.getThresholdCluster().getEntity());
clusterGraceSlider.setValue(model.getGraceCluster().getEntity() + 100);
storageThresholdSlider.setValue(model.getThresholdStorage().getEntity());
storageGraceSlider.setValue(model.getGraceStorage().getEntity() + 100);
}
@Override
public void onSliderValueChange(String name, int value) {
if (name.equals(THRESHOLD_CLUSTER)) {
model.getThresholdCluster().setEntity(value);
} else if (name.equals(GRACE_CLUSTER)) {
model.getGraceCluster().setEntity(value - 100);
} else if (name.equals(THRESHOLD_STORAGE)) {
model.getThresholdStorage().setEntity(value);
} else if (name.equals(GRACE_STORAGE)) {
model.getGraceStorage().setEntity(value - 100);
}
}
}