it.unibo.cs.v2.client.NewMachineWizard.java Source code

Java tutorial

Introduction

Here is the source code for it.unibo.cs.v2.client.NewMachineWizard.java

Source

/* Copyright 2011 Massimo Gengarelli <gengarel@cs.unibo.it>
 * This file is part of Floz Configurator.
 * Floz Configurator is free software: you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * Floz Configurator is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License 
 * along with Floz Configurator. If not, see http://www.gnu.org/licenses/.
 */

package it.unibo.cs.v2.client;

import it.unibo.cs.v2.servlets.CreateMachine;
import it.unibo.cs.v2.servlets.CreateMachineAsync;
import it.unibo.cs.v2.servlets.GetIsoList;
import it.unibo.cs.v2.servlets.GetIsoListAsync;
import it.unibo.cs.v2.shared.MachineInfo;

import java.util.HashMap;
import java.util.LinkedList;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.regexp.shared.RegExp;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.DisclosurePanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextBox;

public class NewMachineWizard extends HTMLPanel
        implements AsyncCallback<LinkedList<HashMap<String, String>>>, ClickHandler, Wizard {
    private final GetIsoListAsync getIsoListProxy = (GetIsoListAsync) GWT.create(GetIsoList.class);
    private final CreateMachineAsync createMachineProxy = (CreateMachineAsync) GWT.create(CreateMachine.class);

    private final ListBox isoListBox = new ListBox();
    private final Button submitButton = new Button("Create");

    private final DisclosurePanel description = new DisclosurePanel("Image Description");
    private final HTML descriptionLabel = new HTML();

    private final HTML errorLabel = new HTML();

    private LinkedList<HashMap<String, String>> isos;

    /* stuff for the new machine */
    private final TextBox name = new TextBox();
    private final TextBox descriptionVM = new TextBox();

    /* buttons for the two disks */
    private final String rb1group = "rb1group";
    private final String rb2group = "rb2group";

    private final RadioButton rb12 = new RadioButton(rb1group, "2GB");
    private final RadioButton rb14 = new RadioButton(rb1group, "4GB");
    private final RadioButton rb18 = new RadioButton(rb1group, "8GB");
    private final RadioButton rb116 = new RadioButton(rb1group, "16GB");
    private final RadioButton[] rb1 = new RadioButton[] { rb12, rb14, rb18, rb116 };

    private final TextBox disk2name = new TextBox();
    private final CheckBox secondDisk = new CheckBox("Enable the second disk");
    private final RadioButton rb22 = new RadioButton(rb2group, "2GB");
    private final RadioButton rb24 = new RadioButton(rb2group, "4GB");
    private final RadioButton rb28 = new RadioButton(rb2group, "8GB");
    private final RadioButton rb216 = new RadioButton(rb2group, "16GB");
    private final RadioButton[] rb2 = new RadioButton[] { rb22, rb24, rb28, rb216 };

    /* networking stuff */
    private final CheckBox virtuaCluster = new CheckBox("Connect to the VirtuaCluster");
    private final CheckBox addNetworkIf = new CheckBox("Create a secondary network interface");
    private final TextBox socketName = new TextBox();
    private final TextBox secondMacAddr = new TextBox();

    private boolean finished = false;

    public NewMachineWizard() {
        super("<h2>New machine wizard</h2>");
        getIsoListProxy.getIsoList(this);
        submitButton.addClickHandler(this);

        description.setContent(descriptionLabel);
        description.setAnimationEnabled(true);

        /**
         * Show a description of the selected ISO.
         */
        isoListBox.addChangeHandler(new ChangeHandler() {

            @Override
            public void onChange(ChangeEvent event) {
                String imageName = isoListBox.getValue(isoListBox.getSelectedIndex());
                for (HashMap<String, String> h : isos) {
                    if (!h.get("name").equals(imageName))
                        continue;
                    else
                        descriptionLabel.setHTML("<b>" + h.get("name") + " " + h.get("version") + "</b><br />"
                                + h.get("description") + "<br />" + "<a href=\"" + h.get("web")
                                + "\">Visit the official website</a>" + "<br />" + "The file is located at: "
                                + h.get("iso"));
                }
            }
        });

        /***
         * Basic stuff (iso image, name and description)
         */
        add(new HTML("<h3>Basic settings</h3>"));

        FlexTable table = new FlexTable();
        table.setWidget(0, 0, new HTML("Select the installation disc for your VM: "));
        table.setWidget(0, 1, isoListBox);

        add(table);
        add(description);

        table = new FlexTable();
        table.setWidget(0, 0, new HTML("Choose a name for your new VM: "));
        table.setWidget(0, 1, name);
        table.setWidget(1, 0, new HTML("Enter a one-line description of it: "));
        table.setWidget(1, 1, descriptionVM);

        add(table);

        /***
         * Storage (hard disks)
         */
        add(new HTML("<h3>Storage settings</h3>"));
        add(secondDisk);

        table = new FlexTable();

        table.setWidget(1, 0, new HTML("Choose a size for the primary disk: "));

        HorizontalPanel tempHP = new HorizontalPanel();
        tempHP.add(rb12);
        tempHP.add(rb14);
        tempHP.add(rb18);
        tempHP.add(rb116);
        table.setWidget(1, 1, tempHP);

        table.setWidget(3, 0,
                new HTML("Choose a size for the secondary disk<span style=\"color: pink;\">*</span>: "));

        tempHP = new HorizontalPanel();
        tempHP.add(rb22);
        tempHP.add(rb24);
        tempHP.add(rb28);
        tempHP.add(rb216);
        table.setWidget(3, 1, tempHP);

        add(table);

        secondDisk.setValue(false);

        /**
         * by default, the secondary disk is not enabled
         */
        disk2name.setEnabled(false);

        rb22.setEnabled(false);
        rb24.setEnabled(false);
        rb28.setEnabled(false);
        rb216.setEnabled(false);

        rb18.setValue(true);
        rb28.setValue(true);

        secondDisk.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                disk2name.setEnabled(secondDisk.getValue());
                rb22.setEnabled(secondDisk.getValue());
                rb24.setEnabled(secondDisk.getValue());
                rb28.setEnabled(secondDisk.getValue());
                rb216.setEnabled(secondDisk.getValue());
            }
        });

        table = new FlexTable();
        add(new HTML("<h3>Networking</h3>"));
        table = new FlexTable();

        table.setWidget(0, 0, virtuaCluster);
        table.setWidget(1, 0, addNetworkIf);
        table.setWidget(2, 0,
                new HTML("Macaddress for the network interface<span style=\"color: red;\">*</span>: "));
        table.setWidget(2, 1, secondMacAddr);
        table.setWidget(3, 0, new HTML("Relative path for the new socket<span style=\"color: blue;\">*</span>: "));
        table.setWidget(3, 1, socketName);

        virtuaCluster.setValue(true);
        addNetworkIf.setValue(false);
        secondMacAddr.setEnabled(false);
        socketName.setEnabled(false);

        addNetworkIf.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                secondMacAddr.setEnabled(addNetworkIf.getValue());
                socketName.setEnabled(addNetworkIf.getValue());
            }
        });

        add(table);
        add(new HTML("<h3>Notes</h3>"));
        add(new HTML("<span style=\"color: red;\">* </span>Leave blank to use the QEMU's default one."));
        add(new HTML("<span style=\"color: blue;\">* </span>Will be created in your home."));
        add(new HTML("<span style=\"color: pink;\">* </span>Extension '.img' will be automatically added."));

        add(errorLabel);
        add(submitButton);
    }

    public void updateList() {
        getIsoListProxy.getIsoList(this);
    }

    @Override
    public void onFailure(Throwable caught) {
        DialogBox errorDialog = new DialogBox();
        errorDialog.setAnimationEnabled(true);
        errorDialog.setWidget(new HTML("An error occured while querying the RPC server, please refresh the page."));
        errorDialog.show();
    }

    @Override
    public void onSuccess(LinkedList<HashMap<String, String>> result) {
        this.isos = result;
        isoListBox.clear();

        // No isos found on the server.
        if (result == null) {
            descriptionLabel.setHTML("No images found on the server.");
            submitButton.setEnabled(false);
            return;
        }

        // Everything seems ok.
        for (HashMap<String, String> h : result)
            isoListBox.addItem(h.get("name"));

        descriptionLabel.setHTML("Select an image to show its description!");
        submitButton.setEnabled(true);
    }

    private void showSuccess(String msg) {
        errorLabel.getElement().getStyle().setColor("green");
        errorLabel.getElement().getStyle().setFontSize(1.4, Unit.EM);

        errorLabel.setHTML(msg);
        errorLabel.setVisible(true);
    }

    private void showError(String error) {
        errorLabel.getElement().getStyle().setColor("red");
        errorLabel.getElement().getStyle().setFontSize(1.4, Unit.EM);

        errorLabel.setHTML(error);
        errorLabel.setVisible(true);
    }

    private void hideError() {
        errorLabel.setVisible(false);
    }

    @Override
    public void onClick(ClickEvent event) {
        final MachineInfo machineInfo = new MachineInfo();
        hideError();

        if (RegExp.compile("[^A-z0-9]").test(name.getText())) {
            showError("Machine name may only contain letters or digits (e.g. MyFirstMachine01)");
            return;
        }

        if (name.getText().equals("")) {
            showError("Machine name can't be blank");
            return;
        }

        machineInfo.setName(name.getText());
        machineInfo.setDescription(descriptionVM.getText());

        for (HashMap<String, String> hm : isos) {
            if (hm.get("name").equals(isoListBox.getValue(isoListBox.getSelectedIndex()))) {
                machineInfo.setIso(hm.get("iso"));
                break;
            }
        }
        //      
        //      if (!disk1name.getText().equals(name.getText())) {
        //         showError("Primary disk name must match the machine's name.");
        //         return;
        //      }
        //      
        machineInfo.setHda(name.getText());
        for (RadioButton b : rb1) {
            if (!b.getValue())
                continue;
            machineInfo.setHdaSize(b.getText());
        }

        //      if (disk2name.isEnabled() && disk2name.getText().equals((""))) {
        //         showError("Disk name can't be blank");
        //         return;
        //      }

        machineInfo.setHdbEnabled(disk2name.isEnabled());
        if (disk2name.isEnabled()) {
            machineInfo.setHdb(name.getText() + "-secondary");
            for (RadioButton b : rb2) {
                if (!b.getValue())
                    continue;
                machineInfo.setHdbSize(b.getText());
            }
        }

        machineInfo.setVirtuacluster(virtuaCluster.getValue());
        machineInfo.setSecondNetwork(addNetworkIf.getValue());

        if (addNetworkIf.getValue() && socketName.getText().equals("")) {
            showError("Socket name can't be blank");
            return;
        }

        machineInfo.setSocketPath(socketName.getText());
        machineInfo.setMacAddress(secondMacAddr.getText());

        createMachineProxy.createMachine(machineInfo, new AsyncCallback<Boolean>() {

            @Override
            public void onFailure(Throwable caught) {
                Window.alert(caught.getMessage());
            }

            @Override
            public void onSuccess(Boolean result) {
                clear();
                add(errorLabel);

                if (result) {
                    showSuccess("Machine successfully created");
                    finished = true;
                    MainPanel.getInstance().refresh();
                } else
                    showError("Error while creating the machine. This is programmers' fault, not yours. "
                            + "Please reload the page and retry.");
            }
        });
    }

    public boolean hasFinished() {
        return finished;
    }
}