package io.eguan.webui.component; /* * #%L * Project eguan * %% * Copyright (C) 2012 - 2017 Oodrive * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import io.eguan.webui.WebUiResources; import io.eguan.webui.WebUiUtils; import io.eguan.webui.WebUiUtils.IntegerAttributeOperation; import io.eguan.webui.WebUiUtils.LongAttributeOperation; import io.eguan.webui.WebUiUtils.StringAttributeOperation; import io.eguan.webui.component.WaitingComponent.Background; import io.eguan.webui.component.window.DeviceDeleteWindow; import io.eguan.webui.component.window.ErrorWindow; import io.eguan.webui.model.DeviceModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Accordion; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.FormLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.OptionGroup; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; /** * The class represents a device item which is a part of a tree items. * * @author oodrive * @author ebredzinski * */ final class DeviceItemComponent implements TreeItemComponent { private static final Logger LOGGER = LoggerFactory.getLogger(DeviceItemComponent.class); private final static String DEACTIVATE = "Deactivate"; private final static String RWACTIVATE = "RW activate"; private final static String ROACTIVATE = "RO activate"; /* Device data representation */ private final DeviceModel model; private final Accordion attr; private static final int ATTRIBUTES_INDEX = 0; private static final int ACTIVATE_INDEX = 1; private static final int TAKE_INDEX = 2; private static final int DELETE_INDEX = 3; DeviceItemComponent(final DeviceModel model) { super(); this.model = model; this.attr = new Accordion(); } @Override public final AbstractComponent init() { final AbstractComponent attrlayout = createAttributes(); attr.addTab(attrlayout, "Attributes", WebUiResources.getSettingsSideIcon(), ATTRIBUTES_INDEX); final AbstractComponent actLayout = createActivate(); attr.addTab(actLayout, "Activation", WebUiResources.getActivateIcon(), ACTIVATE_INDEX); final AbstractComponent takeSnapLayout = createTakeSnap(); attr.addTab(takeSnapLayout, "Take Snapshot", WebUiResources.getSnapshotSideIcon(), TAKE_INDEX); final AbstractComponent deleteLayout = createDelete(); attr.addTab(deleteLayout, "Delete", WebUiResources.getTrashSideIcon(), DELETE_INDEX); return attr; } /** * Update device attributes */ protected final void updateAttributes() { // Tell if this the last selected tab of the accordion final boolean isSelected = attr.getSelectedTab().equals(attr.getTab(ATTRIBUTES_INDEX).getComponent()); // Remove it attr.removeTab(attr.getTab(ATTRIBUTES_INDEX)); // Create a new one with the new attributes value final AbstractComponent attrlayout = createAttributes(); attr.addTab(attrlayout, "Attributes", WebUiResources.getSettingsSideIcon(), ATTRIBUTES_INDEX); // Select it if it was selected if (isSelected) { attr.setSelectedTab(attrlayout); } } /** * Create delete tab in the accordion. * * @return the component. */ @SuppressWarnings("serial") private final AbstractComponent createDelete() { /* root layout */ final VerticalLayout layout = new VerticalLayout(); layout.setSizeFull(); layout.setMargin(true); layout.setSpacing(true); final Label label = new Label("Deleting a device can be done, only if it is de-activated."); layout.addComponent(label); label.setWidth(null); layout.setComponentAlignment(label, Alignment.MIDDLE_CENTER); final Button deleteButton = new Button("Delete"); layout.addComponent(deleteButton); layout.setComponentAlignment(deleteButton, Alignment.BOTTOM_CENTER); deleteButton.addClickListener(new Button.ClickListener() { @Override public void buttonClick(final ClickEvent event) { try { final DeviceDeleteWindow deleteWindow = new DeviceDeleteWindow(model.getItemUuid()); deleteWindow.add(model); } catch (final Exception e) { LOGGER.error("Can not delete device: ", e); } } }); return layout; } /** * Create the component to take a snapshot. * * @return the component */ @SuppressWarnings("serial") private final AbstractComponent createTakeSnap() { final VerticalLayout layout = new VerticalLayout(); layout.setSpacing(true); layout.setMargin(true); final FormLayout takeSnapLayout = new FormLayout(); takeSnapLayout.setMargin(true); takeSnapLayout.setImmediate(true); takeSnapLayout.setWidth(null); layout.addComponent(takeSnapLayout); layout.setComponentAlignment(takeSnapLayout, Alignment.MIDDLE_CENTER); // Enter name final TextField vvrName = new TextField("Name", ""); takeSnapLayout.addComponent(vvrName); // take button final Button take = new Button("Take snapshot"); layout.addComponent(take); layout.setComponentAlignment(take, Alignment.MIDDLE_CENTER); take.addClickListener(new Button.ClickListener() { @Override public void buttonClick(final ClickEvent event) { try { model.takeDeviceSnapshot(vvrName.getValue()); Notification.show("New snapshot created", Notification.Type.TRAY_NOTIFICATION); } catch (final Exception e) { final ErrorWindow err = new ErrorWindow("Snapshot not taken: " + e.getMessage()); err.add(model); } } }); return layout; } /** * Create the component to activate/deactivate a device. * * @return the component */ @SuppressWarnings("serial") private final AbstractComponent createActivate() { final VerticalLayout rootlayout = new VerticalLayout(); rootlayout.setMargin(true); rootlayout.setSpacing(true); final OptionGroup activate = new OptionGroup("Select an option: "); rootlayout.addComponent(activate); rootlayout.setComponentAlignment(activate, Alignment.MIDDLE_CENTER); activate.setNullSelectionAllowed(false); activate.setHtmlContentAllowed(true); activate.setImmediate(true); activate.addItem(DEACTIVATE); activate.addItem(RWACTIVATE); activate.addItem(ROACTIVATE); final boolean isActivated = model.isDeviceActive(); if (isActivated) { final boolean isReadOnly = model.isDeviceReadOnly(); if (isReadOnly) { activate.select(ROACTIVATE); // rw is not authorized, deactivate first activate.setItemEnabled(RWACTIVATE, false); } else { activate.select(RWACTIVATE); // ro is not authorized, deactivate first activate.setItemEnabled(ROACTIVATE, false); } } else { activate.select(DEACTIVATE); } activate.addValueChangeListener(new ValueChangeListener() { @Override public void valueChange(final ValueChangeEvent event) { final String valueString = String.valueOf(event.getProperty().getValue()); if (valueString.equals(DEACTIVATE)) { final String action = DEACTIVATE; // Run activation in background WaitingComponent.executeBackground(model, new Background() { @Override public void processing() { model.deActivateDevice(); } @Override public void postProcessing() { activate.setItemEnabled(RWACTIVATE, true); activate.setItemEnabled(ROACTIVATE, true); updateAttributes(); Notification.show("Device " + action + "d", Notification.Type.TRAY_NOTIFICATION); } }); } else if (valueString.equals(RWACTIVATE)) { final String action = RWACTIVATE; WaitingComponent.executeBackground(model, new Background() { @Override public void processing() { model.activateDeviceRW(); } @Override public void postProcessing() { // ro is not authorized, deactivate first activate.setItemEnabled(ROACTIVATE, false); updateAttributes(); Notification.show("Device " + action + "d", Notification.Type.TRAY_NOTIFICATION); } }); } else if (valueString.equals(ROACTIVATE)) { final String action = ROACTIVATE; WaitingComponent.executeBackground(model, new Background() { @Override public void processing() { model.activateDeviceRO(); } @Override public void postProcessing() { // rw is not authorized, deactivate first activate.setItemEnabled(RWACTIVATE, false); updateAttributes(); Notification.show("Device " + action + "d", Notification.Type.TRAY_NOTIFICATION); } }); } } }); return rootlayout; } /** * Create attributes component. * * @return the component */ private final AbstractComponent createAttributes() { final VerticalLayout layout = new VerticalLayout(); final FormLayout deviceAttributesLayout = new FormLayout(); deviceAttributesLayout.setMargin(true); deviceAttributesLayout.setWidth(null); deviceAttributesLayout.setImmediate(true); layout.addComponent(deviceAttributesLayout); layout.setComponentAlignment(deviceAttributesLayout, Alignment.MIDDLE_CENTER); // Enter NAME WebUiUtils.createFieldString(new StringAttributeOperation() { @Override public void setStringValue(final String value) { model.setDeviceName(value); } @Override public String getStringValue() { return model.getDeviceName(); } }, "Name", deviceAttributesLayout, model); // Enter DESCRIPTION WebUiUtils.createFieldString(new StringAttributeOperation() { @Override public void setStringValue(final String value) { model.setDeviceDescription(value); } @Override public String getStringValue() { return model.getDeviceDescription(); } }, "Description", deviceAttributesLayout, model); // Enter UUID (not editable) final TextField deviceUUID = new TextField("UUID", model.getItemUuid().toString()); deviceUUID.setReadOnly(true); deviceUUID.setWidth("300px"); deviceAttributesLayout.addComponent(deviceUUID); // Enter active final TextField deviceActive = new TextField("Active"); if (model.isDeviceActive()) { deviceActive.setValue("yes"); } else { deviceActive.setValue("no"); } deviceActive.setReadOnly(true); deviceActive.setSizeFull(); deviceAttributesLayout.addComponent(deviceActive); // Enter read only final TextField deviceReadOnly = new TextField("Read Only"); if (model.isDeviceReadOnly()) { deviceReadOnly.setValue("yes"); } else { deviceReadOnly.setValue("no"); } deviceReadOnly.setReadOnly(true); deviceReadOnly.setSizeFull(); deviceAttributesLayout.addComponent(deviceReadOnly); // Enter size WebUiUtils.createFieldLong(new LongAttributeOperation() { @Override public void setLongValue(final long value) { model.setDeviceSize(value); } @Override public long getLongValue() { return model.getDeviceSize(); } }, "Size", deviceAttributesLayout, model); // Enter IQN WebUiUtils.createFieldString(new StringAttributeOperation() { @Override public void setStringValue(final String value) { model.setDeviceIqn(value); } @Override public String getStringValue() { return model.getDeviceIqn(); } }, "IQN", deviceAttributesLayout, model); // Enter Alias WebUiUtils.createFieldString(new StringAttributeOperation() { @Override public void setStringValue(final String value) { model.setDeviceIscsiAlias(value); } @Override public String getStringValue() { return model.getDeviceIscsiAlias(); } }, "iSCSI Alias", deviceAttributesLayout, model); // Enter iscsi block size WebUiUtils.createFieldInteger(new IntegerAttributeOperation() { @Override public void setIntegerValue(final int value) { model.setDeviceIscsiBlockSize(value); } @Override public int getIntegerValue() { return model.getDeviceIscsiBlockSize(); } }, "iSCSI Block Size", deviceAttributesLayout, model, true); return layout; } }