package org.ovirt.engine.ui.webadmin.widget.table.column; import java.util.Comparator; import org.ovirt.engine.core.common.TimeZoneType; import org.ovirt.engine.core.common.businessentities.GuestAgentStatus; import org.ovirt.engine.core.common.businessentities.OsType; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmPauseStatus; import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface; import org.ovirt.engine.core.common.utils.PairQueryable; import org.ovirt.engine.core.compat.WindowsJavaTimezoneMapping; import org.ovirt.engine.ui.common.widget.table.column.AbstractColumn; import org.ovirt.engine.ui.uicommonweb.Linq; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicompat.EnumTranslator; import org.ovirt.engine.ui.webadmin.ApplicationConstants; import org.ovirt.engine.ui.webadmin.gin.AssetProvider; import org.ovirt.engine.ui.webadmin.widget.table.cell.VmStatusCell; import com.google.gwt.safehtml.shared.SafeHtml; import com.google.gwt.safehtml.shared.SafeHtmlUtils; /** * Image column that corresponds to XAML {@code VmStatusTemplate}. */ public class VmStatusColumn<T> extends AbstractColumn<T, VM> { private static final ApplicationConstants constants = AssetProvider.getConstants(); public VmStatusColumn() { super(new VmStatusCell()); } @Override public VM getValue(T object) { if (object instanceof VM){ return (VM)object; }if (object instanceof PairQueryable && ((PairQueryable) object).getSecond() instanceof VM){ return ((PairQueryable<VmNetworkInterface, VM>) object).getSecond(); } return null; } public void makeSortable() { makeSortable(Comparator.comparing( o -> getValue(o) == null ? null : getValue(o).getStatus(), Linq.IdentifiableComparator)); } @Override public SafeHtml getTooltip(T object) { String tooltip; EnumTranslator translator = EnumTranslator.getInstance(); VM vm = getValue(object); if (vm == null) { return null; } // the tooltip always has at least the vm status tooltip = getStatusTooltipText(vm.getStatus()); // optionally, the vm status icon gets an alert exclamation. Indicate why. if (needsAlert(vm)) { if (isUpdateNeeded(vm)) { tooltip += "<br/><br/>" + constants.newtools(); //$NON-NLS-1$ } if (hasPauseError(vm)) { tooltip += "<br/><br/>" + translator.translate(vm.getVmPauseStatus()); //$NON-NLS-1$ } if (vm.getStatus() == VMStatus.Up) { if (hasGuestAgent(vm)) { if (hasDifferentTimezone(vm)) { tooltip += "<br/><br/>" + constants.guestTimezoneDiffers(); //$NON-NLS-1$ } if (hasDifferentOSType(vm)) { tooltip += "<br/><br/>" + constants.guestOSDiffers(); //$NON-NLS-1$ } } else { tooltip += "<br/><br/>" + constants.guestAgentNotAvailable(); //$NON-NLS-1$ } } } if (tooltip != null) { return SafeHtmlUtils.fromSafeConstant(tooltip); } return null; } public static boolean hasGuestAgent(VM vm) { return vm.getTimeZone() != null && vm.getGuestOsType() != null && vm.getGuestOsType() != OsType.Other; } public static boolean needsAlert(VM vm) { boolean alertRequired = false; if (vm.getStatus() == VMStatus.Up) { alertRequired = !hasGuestAgent(vm) || hasDifferentTimezone(vm) || hasDifferentOSType(vm); } return alertRequired || isUpdateNeeded(vm) || hasPauseError(vm); } private static boolean hasDifferentOSType(VM vm) { return AsyncDataProvider.getInstance().isWindowsOsType(vm.getVmOsId()) != (vm.getGuestOsType() == OsType.Windows); } private static boolean hasDifferentTimezone(VM vm) { if (AsyncDataProvider.getInstance().isWindowsOsType(vm.getVmOsId())) { String timeZone = vm.getTimeZone(); if (timeZone != null && !timeZone.isEmpty()) { int offset = 0; String javaZoneId = null; // convert to java & calculate offset javaZoneId = WindowsJavaTimezoneMapping.get(timeZone); if (javaZoneId != null) { offset = TimeZoneType.GENERAL_TIMEZONE.getStandardOffset(javaZoneId); } if (vm.getGuestOsTimezoneOffset() != offset) { return true; } } } return false; } private static boolean isUpdateNeeded(VM vm) { return vm.getStatus() == VMStatus.Up && vm.getGuestAgentStatus() == GuestAgentStatus.UpdateNeeded; } private static boolean hasPauseError(VM vm) { return vm.getVmPauseStatus() != VmPauseStatus.NONE && vm.getVmPauseStatus() != VmPauseStatus.NOERR; } private String getStatusTooltipText(VMStatus status) { switch (status) { case Up: return constants.up(); case Down: return constants.down(); case SavingState: return constants.vmStatusSaving(); case RestoringState: return constants.restoring(); case PoweringUp: return constants.poweringUp(); case PoweringDown: return constants.poweringDown(); case RebootInProgress: return constants.rebooting(); case WaitForLaunch: return constants.waitForLaunchStatus(); case ImageLocked: return constants.imageLocked(); case MigratingFrom: return constants.migrating(); case MigratingTo: return constants.migrating(); case Suspended: return constants.suspended(); case Paused: return constants.paused(); case Unknown: return constants.unknown(); case Unassigned: return constants.unassigned(); case NotResponding: return constants.notResponding(); default: break; } return null; } }