package org.ovirt.engine.ui.webadmin.section.main.view.popup.vm;
import java.util.ArrayList;
import java.util.List;
import org.ovirt.engine.core.common.businessentities.Cluster;
import org.ovirt.engine.core.common.businessentities.OriginType;
import org.ovirt.engine.core.common.businessentities.Quota;
import org.ovirt.engine.core.common.businessentities.StorageDomain;
import org.ovirt.engine.core.common.businessentities.VM;
import org.ovirt.engine.core.common.businessentities.network.VmInterfaceType;
import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
import org.ovirt.engine.core.common.businessentities.network.VnicProfileView;
import org.ovirt.engine.core.common.businessentities.profiles.CpuProfile;
import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
import org.ovirt.engine.core.common.businessentities.storage.VolumeType;
import org.ovirt.engine.ui.common.CommonApplicationTemplates;
import org.ovirt.engine.ui.common.editor.UiCommonEditorDriver;
import org.ovirt.engine.ui.common.idhandler.WithElementId;
import org.ovirt.engine.ui.common.uicommon.model.DetailModelProvider;
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.ListModelListBoxOnlyEditor;
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.renderer.EnumRenderer;
import org.ovirt.engine.ui.common.widget.renderer.NullSafeRenderer;
import org.ovirt.engine.ui.common.widget.renderer.StorageDomainFreeSpaceRenderer;
import org.ovirt.engine.ui.common.widget.renderer.StringRenderer;
import org.ovirt.engine.ui.common.widget.table.column.AbstractCheckboxColumn;
import org.ovirt.engine.ui.common.widget.table.column.AbstractDiskSizeColumn;
import org.ovirt.engine.ui.common.widget.table.column.AbstractEnumColumn;
import org.ovirt.engine.ui.common.widget.table.column.AbstractImageResourceColumn;
import org.ovirt.engine.ui.common.widget.table.column.AbstractSafeHtmlColumn;
import org.ovirt.engine.ui.common.widget.table.column.AbstractTextColumn;
import org.ovirt.engine.ui.common.widget.table.header.ImageResourceHeader;
import org.ovirt.engine.ui.common.widget.uicommon.disks.DisksViewColumns;
import org.ovirt.engine.ui.uicommonweb.models.HasEntity;
import org.ovirt.engine.ui.uicommonweb.models.SearchableListModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportEntityData;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportNetworkData;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportSource;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportVmData;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportVmFromExternalProviderModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.ImportVmModel;
import org.ovirt.engine.ui.uicommonweb.models.vms.VmImportGeneralModel;
import org.ovirt.engine.ui.webadmin.ApplicationConstants;
import org.ovirt.engine.ui.webadmin.ApplicationMessages;
import org.ovirt.engine.ui.webadmin.ApplicationResources;
import org.ovirt.engine.ui.webadmin.section.main.presenter.popup.vm.ImportVmFromExternalProviderPopupPresenterWidget;
import org.ovirt.engine.ui.webadmin.section.main.view.popup.storage.backup.ImportVmGeneralSubTabView;
import org.ovirt.engine.ui.webadmin.widget.table.cell.CustomSelectionCell;
import org.ovirt.engine.ui.webadmin.widget.table.column.VmTypeColumn;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
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.gwt.user.client.ui.SplitLayoutPanel;
import com.google.gwt.user.client.ui.TabLayoutPanel;
import com.google.gwt.view.client.NoSelectionModel;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;
public class ImportVmFromExternalProviderPopupView extends AbstractModelBoundPopupView<ImportVmFromExternalProviderModel> implements ImportVmFromExternalProviderPopupPresenterWidget.ViewDef {
interface Driver extends UiCommonEditorDriver<ImportVmFromExternalProviderModel, ImportVmFromExternalProviderPopupView> {
}
interface ViewUiBinder extends UiBinder<SimpleDialogPanel, ImportVmFromExternalProviderPopupView> {
ViewUiBinder uiBinder = GWT.create(ViewUiBinder.class);
}
@UiField
WidgetStyle style;
@UiField(provided = true)
@Path(value = "cluster.selectedItem")
ListModelListBoxEditor<Cluster> destClusterEditor;
@UiField(provided = true)
@Path(value = "cpuProfiles.selectedItem")
ListModelListBoxEditor<CpuProfile> cpuProfileEditor;
@UiField(provided = true)
@Path(value = "clusterQuota.selectedItem")
ListModelListBoxEditor<Quota> destClusterQuotaEditor;
@UiField(provided = true)
@Path(value = "storage.selectedItem")
ListModelListBoxEditor<StorageDomain> destStorageEditor;
@UiField(provided = true)
@Path(value = "allocation.selectedItem")
ListModelListBoxEditor<VolumeType> disksAllocationEditor;
@UiField(provided = true)
@Path(value = "iso.selectedItem")
@WithElementId("iso")
public ListModelListBoxOnlyEditor<String> cdImageEditor;
@UiField(provided = true)
@Path(value = "attachDrivers.entity")
@WithElementId("attachDrivers")
public EntityModelCheckBoxEditor attachDriversEditor;
@UiField
SplitLayoutPanel splitLayoutPanel;
@UiField
@Ignore
Label message;
@UiField
@Ignore
Label winWithoutVirtioMessage;
@Ignore
ListModelObjectCellTable<ImportVmData, ImportVmFromExternalProviderModel> table;
@Ignore
ListModelObjectCellTable<DiskImage, SearchableListModel> diskTable;
@Ignore
ListModelObjectCellTable<VmNetworkInterface, SearchableListModel> nicTable;
@Ignore
protected TabLayoutPanel subTabLayoutPanel = null;
boolean firstSelection = false;
private ImportVmGeneralSubTabView generalView;
private CustomSelectionCell customSelectionCellNetwork;
protected ImportVmFromExternalProviderModel importModel;
private final Driver driver = GWT.create(Driver.class);
protected final ApplicationConstants constants;
protected final ApplicationResources resources;
protected final ApplicationMessages messages;
@Inject
public ImportVmFromExternalProviderPopupView(EventBus eventBus,
ApplicationResources resources,
ApplicationConstants constants,
ApplicationMessages messages) {
super(eventBus);
this.constants = constants;
this.resources = resources;
this.messages = messages;
initListBoxEditors();
initWidget(ViewUiBinder.uiBinder.createAndBindUi(this));
applyStyles();
localize(constants);
initTables();
driver.initialize(this);
}
protected void applyStyles() {
attachDriversEditor.addContentWidgetContainerStyleName(style.cdAttachedLabelWidth());
}
private void initTables() {
initMainTable();
initNicsTable();
initDiskTable();
}
protected void initMainTable() {
this.table = new ListModelObjectCellTable<>();
AbstractCheckboxColumn<ImportVmData> cloneVMColumn = new AbstractCheckboxColumn<ImportVmData>((index, model, value) -> {
model.getClone().setEntity(value);
table.asEditor().edit(importModel);
}) {
@Override
public Boolean getValue(ImportVmData model) {
return model.getClone().getEntity();
}
@Override
protected boolean canEdit(ImportVmData model) {
return model.getClone().getIsChangable();
}
@Override
protected String getDisabledMessage(ImportVmData model) {
return model.getClone().getChangeProhibitionReason();
}
};
table.addColumn(cloneVMColumn, constants.cloneVM(), "50px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> nameColumn = new AbstractTextColumn<ImportVmData>() {
@Override
public String getValue(ImportVmData object) {
return object.getName();
}
};
table.addColumn(nameColumn, constants.nameVm(), "150px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> originColumn = new AbstractEnumColumn<ImportVmData, OriginType>() {
@Override
protected OriginType getRawValue(ImportVmData object) {
return object.getVm().getOrigin();
}
};
table.addColumn(originColumn, constants.originVm(), "100px"); //$NON-NLS-1$
table.addColumn(
new AbstractSafeHtmlColumn<ImportVmData>() {
@Override
public SafeHtml getValue(ImportVmData object) {
return VmTypeColumn.getRenderedValue(object.getVm());
}
}, constants.empty(), "30px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> memoryColumn = new AbstractTextColumn<ImportVmData>() {
@Override
public String getValue(ImportVmData object) {
return messages.megabytes(String.valueOf(object.getVm().getVmMemSizeMb()));
}
};
table.addColumn(memoryColumn, constants.memoryVm(), "100px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> cpuColumn = new AbstractTextColumn<ImportVmData>() {
@Override
public String getValue(ImportVmData object) {
return String.valueOf(object.getVm().getNumOfCpus());
}
};
table.addColumn(cpuColumn, constants.cpusVm(), "50px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> archColumn = new AbstractTextColumn<ImportVmData>() {
@Override
public String getValue(ImportVmData object) {
return String.valueOf(object.getVm().getClusterArch());
}
};
table.addColumn(archColumn, constants.architectureVm(), "50px"); //$NON-NLS-1$
AbstractTextColumn<ImportVmData> diskColumn = new AbstractTextColumn<ImportVmData>() {
@Override
public String getValue(ImportVmData object) {
return String.valueOf(object.getVm().getDiskMap().size());
}
};
table.addColumn(diskColumn, constants.disksVm(), "50px"); //$NON-NLS-1$
ScrollPanel sp = new ScrollPanel();
sp.add(table);
splitLayoutPanel.add(sp);
table.getElement().getStyle().setPosition(Position.RELATIVE);
}
private void localize(ApplicationConstants constants) {
destClusterEditor.setLabel(constants.importVm_destCluster());
destClusterQuotaEditor.setLabel(constants.importVm_destClusterQuota());
destStorageEditor.setLabel(constants.storageDomainDisk());
cpuProfileEditor.setLabel(constants.cpuProfileLabel());
disksAllocationEditor.setLabel(constants.allocationDisk());
attachDriversEditor.setLabel(constants.attachVirtioDrivers());
}
private void initListBoxEditors() {
destClusterEditor = new ListModelListBoxEditor<>(new NullSafeRenderer<Cluster>() {
@Override
public String renderNullSafe(Cluster object) {
return object.getName();
}
});
destClusterQuotaEditor = new ListModelListBoxEditor<>(new NullSafeRenderer<Quota>() {
@Override
public String renderNullSafe(Quota object) {
return object.getQuotaName();
}
});
destStorageEditor = new ListModelListBoxEditor<>(new StorageDomainFreeSpaceRenderer());
cpuProfileEditor = new ListModelListBoxEditor<>(new NullSafeRenderer<CpuProfile>() {
@Override
protected String renderNullSafe(CpuProfile object) {
return object.getName();
}
});
disksAllocationEditor = new ListModelListBoxEditor<>(new NullSafeRenderer<VolumeType>() {
@Override
protected String renderNullSafe(VolumeType object) {
return new EnumRenderer<VolumeType>().render(object);
}
});
attachDriversEditor = new EntityModelCheckBoxEditor(Align.LEFT);
cdImageEditor = new ListModelListBoxOnlyEditor<>(new StringRenderer<String>());
}
@Override
public void edit(final ImportVmFromExternalProviderModel importModel) {
this.importModel = importModel;
table.asEditor().edit(importModel);
importModel.getPropertyChangedEvent().addListener((ev, sender, args) -> {
if (args.propertyName.equals(ImportVmFromExternalProviderModel.ON_DISK_LOAD)) {
table.asEditor().edit(table.asEditor().flush());
} else if (args.propertyName.equals("Message")) { ////$NON-NLS-1$
message.setText(importModel.getMessage());
} else if (args.propertyName.equals("WinWithoutVirtioMessage")) { ////$NON-NLS-1$
winWithoutVirtioMessage.setText(importModel.getWinWithoutVirtioMessage());
}
});
SingleSelectionModel<Object> selectionModel =
(SingleSelectionModel<Object>) table.getSelectionModel();
selectionModel.addSelectionChangeHandler(event -> {
if (!firstSelection) {
importModel.setActiveDetailModel((HasEntity<?>) importModel.getDetailModels().get(0));
setGeneralViewSelection(((ImportEntityData) importModel.getSelectedItem()).getEntity());
firstSelection = true;
}
splitLayoutPanel.clear();
splitLayoutPanel.addSouth(subTabLayoutPanel, 230);
ScrollPanel sp = new ScrollPanel();
sp.add(table);
splitLayoutPanel.add(sp);
table.getElement().getStyle().setPosition(Position.RELATIVE);
});
initSubTabLayoutPanel();
nicTable.asEditor().edit((SearchableListModel) importModel.getDetailModels().get(1));
diskTable.asEditor().edit((SearchableListModel) importModel.getDetailModels().get(2));
driver.edit(importModel);
}
private void addNetworkColumn() {
customSelectionCellNetwork = new CustomSelectionCell(new ArrayList<String>());
customSelectionCellNetwork.setStyle(style.cellSelectBox());
Column<VmNetworkInterface, String> networkColumn = new Column<VmNetworkInterface, String>(customSelectionCellNetwork) {
@Override
public String getValue(VmNetworkInterface iface) {
ImportNetworkData importNetworkData = importModel.getNetworkImportData(iface);
List<String> networkNames = importNetworkData.getNetworkNames();
((CustomSelectionCell) getCell()).setOptions(networkNames);
if (networkNames.isEmpty()) {
return ""; //$NON-NLS-1$
}
String selectedNetworkName = importNetworkData.getSelectedNetworkName();
return selectedNetworkName != null ? selectedNetworkName : networkNames.get(0);
}
};
networkColumn.setFieldUpdater((index, iface, value) -> {
importModel.getNetworkImportData(iface).setSelectedNetworkName(value);
nicTable.asEditor().edit(importModel.getImportNetworkInterfaceListModel());
});
nicTable.addColumn(networkColumn, constants.networkNameInterface(), "150px"); //$NON-NLS-1$
}
private void addNetworkProfileColumn() {
customSelectionCellNetwork = new CustomSelectionCell(new ArrayList<String>());
customSelectionCellNetwork.setStyle(style.cellSelectBox());
Column<VmNetworkInterface, String> profileColumn = new Column<VmNetworkInterface, String>(customSelectionCellNetwork) {
@Override
public String getValue(VmNetworkInterface iface) {
ImportNetworkData importNetworkData = importModel.getNetworkImportData(iface);
List<String> networkProfileNames = new ArrayList<>();
for (VnicProfileView networkProfile : importNetworkData.getFilteredNetworkProfiles()) {
networkProfileNames.add(networkProfile.getName());
}
((CustomSelectionCell) getCell()).setOptions(networkProfileNames);
if (networkProfileNames.isEmpty()) {
return ""; //$NON-NLS-1$
}
VnicProfileView selectedNetworkProfile = importModel.getNetworkImportData(iface).getSelectedNetworkProfile();
return selectedNetworkProfile != null ? selectedNetworkProfile.getName() : networkProfileNames.get(0);
}
};
profileColumn.setFieldUpdater((index, iface, value) -> importModel.getNetworkImportData(iface).setSelectedNetworkProfile(value));
nicTable.addColumn(profileColumn, constants.profileNameInterface(), "150px"); //$NON-NLS-1$
}
protected void setGeneralViewSelection(Object selectedItem) {
generalView.setMainTabSelectedItem((VM) selectedItem);
}
private void initSubTabLayoutPanel() {
if (subTabLayoutPanel == null) {
subTabLayoutPanel = new TabLayoutPanel(CommonApplicationTemplates.TAB_BAR_HEIGHT, Unit.PX);
subTabLayoutPanel.addSelectionHandler(event -> subTabLayoutPanelSelectionChanged(event.getSelectedItem()));
initGeneralSubTabView();
ScrollPanel nicPanel = new ScrollPanel();
nicPanel.add(nicTable);
subTabLayoutPanel.add(nicPanel, constants.importVmNetworkIntefacesSubTabLabel());
ScrollPanel diskPanel = new ScrollPanel();
diskPanel.add(diskTable);
subTabLayoutPanel.add(diskPanel, constants.importVmDisksSubTabLabel());
}
}
protected void subTabLayoutPanelSelectionChanged(Integer selectedItem) {
if (importModel != null) {
importModel.setActiveDetailModel((HasEntity<?>) importModel.getDetailModels().get(selectedItem));
}
}
protected void initGeneralSubTabView() {
ScrollPanel generalPanel = new ScrollPanel();
DetailModelProvider<ImportVmModel, VmImportGeneralModel> modelProvider =
new DetailModelProvider<ImportVmModel, VmImportGeneralModel>() {
@Override
public VmImportGeneralModel getModel() {
VmImportGeneralModel model = (VmImportGeneralModel) importModel.getDetailModels().get(0);
model.setSource(ImportSource.VMWARE);
return model;
}
@Override
public void onSubTabSelected() {
}
@Override
public void onSubTabDeselected() {
}
};
generalView = new ImportVmGeneralSubTabView(modelProvider);
generalPanel.add(generalView);
subTabLayoutPanel.add(generalPanel, constants.importVmGeneralSubTabLabel());
}
@Override
public ImportVmFromExternalProviderModel flush() {
return driver.flush();
}
@Override
public void cleanup() {
driver.cleanup();
}
private void initNicsTable() {
nicTable = new ListModelObjectCellTable<>();
nicTable.enableColumnResizing();
AbstractTextColumn<VmNetworkInterface> nameColumn = new AbstractTextColumn<VmNetworkInterface>() {
@Override
public String getValue(VmNetworkInterface object) {
return object.getName();
}
};
nicTable.addColumn(nameColumn, constants.nameInterface(), "125px"); //$NON-NLS-1$
AbstractTextColumn<VmNetworkInterface> originalNetworkNameColumn = new AbstractTextColumn<VmNetworkInterface>() {
@Override
public String getValue(VmNetworkInterface object) {
return object.getRemoteNetworkName();
}
};
nicTable.addColumn(originalNetworkNameColumn, constants.originalNetworkNameInterface(), "160px"); //$NON-NLS-1$
addNetworkColumn();
addNetworkProfileColumn();
AbstractTextColumn<VmNetworkInterface> typeColumn = new AbstractEnumColumn<VmNetworkInterface, VmInterfaceType>() {
@Override
protected VmInterfaceType getRawValue(VmNetworkInterface object) {
return VmInterfaceType.forValue(object.getType());
}
};
nicTable.addColumn(typeColumn, constants.typeInterface(), "150px"); //$NON-NLS-1$
AbstractTextColumn<VmNetworkInterface> macColumn = new AbstractTextColumn<VmNetworkInterface>() {
@Override
public String getValue(VmNetworkInterface object) {
return object.getMacAddress();
}
};
nicTable.addColumn(macColumn, constants.macInterface(), "150px"); //$NON-NLS-1$
nicTable.getElement().getStyle().setPosition(Position.RELATIVE);
nicTable.setSelectionModel(new NoSelectionModel<VmNetworkInterface>());
}
private void initDiskTable() {
diskTable = new ListModelObjectCellTable<>();
diskTable.enableColumnResizing();
AbstractTextColumn<DiskImage> aliasColumn = new AbstractTextColumn<DiskImage>() {
@Override
public String getValue(DiskImage object) {
return object.getDiskAlias();
}
};
diskTable.addColumn(aliasColumn, constants.aliasDisk(), "300px"); //$NON-NLS-1$
AbstractImageResourceColumn<DiskImage> bootableDiskColumn = new AbstractImageResourceColumn<DiskImage>() {
@Override
public ImageResource getValue(DiskImage object) {
boolean isBoot = !object.getDiskVmElements().isEmpty() && object.getDiskVmElements().iterator().next().isBoot();
return isBoot ? getDefaultImage() : null;
}
@Override
public ImageResource getDefaultImage() {
return resources.bootableDiskIcon();
}
@Override
public SafeHtml getTooltip(DiskImage object) {
if (!object.getDiskVmElements().isEmpty() && object.getDiskVmElements().iterator().next().isBoot()) {
return SafeHtmlUtils.fromSafeConstant(constants.bootableDisk());
}
return null;
}
};
diskTable.addColumn(bootableDiskColumn,
new ImageResourceHeader(DisksViewColumns.bootableDiskColumn.getDefaultImage(),
SafeHtmlUtils.fromSafeConstant(constants.bootableDisk())),
"30px"); //$NON-NLS-1$
AbstractDiskSizeColumn<DiskImage> sizeColumn = new AbstractDiskSizeColumn<DiskImage>() {
@Override
protected Long getRawValue(DiskImage object) {
return object.getSize();
}
};
diskTable.addColumn(sizeColumn, constants.provisionedSizeDisk(), "130px"); //$NON-NLS-1$
AbstractDiskSizeColumn<DiskImage> actualSizeColumn = new AbstractDiskSizeColumn<DiskImage>() {
@Override
protected Long getRawValue(DiskImage object) {
return object.getActualSizeInBytes();
}
};
diskTable.addColumn(actualSizeColumn, constants.sizeDisk(), "130px"); //$NON-NLS-1$
diskTable.setSelectionModel(new NoSelectionModel<DiskImage>());
diskTable.getElement().getStyle().setPosition(Position.RELATIVE);
}
interface WidgetStyle extends CssResource {
String cellSelectBox();
String cdAttachedLabelWidth();
}
}