edu.ucsb.eucalyptus.admin.client.WalrusInfoTable.java Source code

Java tutorial

Introduction

Here is the source code for edu.ucsb.eucalyptus.admin.client.WalrusInfoTable.java

Source

/*******************************************************************************
*Copyright (c) 2009  Eucalyptus Systems, Inc.
* 
*  This program 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, only version 3 of the License.
* 
* 
*  This file 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 this program.  If not, see <http://www.gnu.org/licenses/>.
* 
*  Please contact Eucalyptus Systems, Inc., 130 Castilian
*  Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
*  if you need additional information or have any questions.
* 
*  This file may incorporate work covered under the following copyright and
*  permission notice:
* 
*    Software License Agreement (BSD License)
* 
*    Copyright (c) 2008, Regents of the University of California
*    All rights reserved.
* 
*    Redistribution and use of this software in source and binary forms, with
*    or without modification, are permitted provided that the following
*    conditions are met:
* 
*      Redistributions of source code must retain the above copyright notice,
*      this list of conditions and the following disclaimer.
* 
*      Redistributions in binary form must reproduce the above copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
* 
*    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
*    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
*    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
*    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
*    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
*    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
*    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
*    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
*    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
*    THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
*    LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
*    SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
*    IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
*    BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
*    THE REGENTS DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
*    OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
*    WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
*    ANY SUCH LICENSES OR RIGHTS.
*******************************************************************************/
package edu.ucsb.eucalyptus.admin.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;

import edu.ucsb.eucalyptus.admin.client.ClusterInfoTable.DeleteCallback;
import edu.ucsb.eucalyptus.admin.client.SystemConfigTable.ChangeCallback;
import edu.ucsb.eucalyptus.admin.client.SystemConfigTable.FocusHandler;

import java.util.ArrayList;
import java.util.List;

// dmitrii TODO: remove commented out lines once the CSS-based design is confirmed

public class WalrusInfoTable extends VerticalPanel implements ClickHandler {

    private static int maxWalruses = 1; // TODO: bump this up once we can do more than 1
    private static Label noWalrusesLabel = new Label();
    private static Label statusLabel = new Label();
    private Grid grid = new Grid();
    private EucaButton add_button = new EucaButton("Register Walrus", this);
    private static HTML hint = new HTML();
    private List<WalrusInfoWeb> walrusList = new ArrayList<WalrusInfoWeb>();
    private static String sessionId;
    private static String warningMessage = "Note: registering Walrus requires synchronization of keys among all nodes, which cannot be done through this interface.  See documentation for details.";

    public WalrusInfoTable(String sessionId) {
        this.sessionId = sessionId;
        this.setStyleName("euca-config-component");
        this.setSpacing(2);
        this.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
        //      this.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        Label walrusesHeader = new Label("Walrus Configuration:");
        walrusesHeader.setStyleName("euca-section-header");
        this.add(walrusesHeader);
        this.noWalrusesLabel.setText("No Walrus hosts registered");
        this.noWalrusesLabel.setStyleName("euca-greeting-disabled");
        HorizontalPanel grid_and_hint = new HorizontalPanel();
        grid_and_hint.add(this.grid);
        grid_and_hint.add(this.hint);
        this.hint.setWidth("100");
        this.add(grid_and_hint);
        HorizontalPanel hpanel = new HorizontalPanel();
        hpanel.setSpacing(2);
        hpanel.add(add_button);
        hpanel.add(new EucaButton("Save Walrus configuration", new SaveCallback(this)));
        hpanel.add(this.statusLabel);
        //      this.statusLabel.setWidth ("250");
        this.statusLabel.setText("");
        this.statusLabel.setStyleName("euca-greeting-pending");
        this.add(hpanel);
        rebuildTable();
        EucalyptusWebBackend.App.getInstance().getWalrusList(this.sessionId, new GetWalrusListCallback(this));
    }

    public void onClick(ClickEvent event) // Register walrus button
    {
        this.walrusList.add(new WalrusInfoWeb("Walrus", "host", 8773 /** FIXME: DRAMATICALLY: URGENTLY **/
                , new ArrayList<String>())); //these values are just defaults
        this.rebuildTable();
        this.statusLabel.setText("Unsaved changes");
        this.statusLabel.setStyleName("euca-greeting-warning");
    }

    private void rebuildTable() {
        if (this.walrusList.isEmpty()) {
            this.grid.setVisible(false);
            this.noWalrusesLabel.setVisible(true);
            this.add_button.setEnabled(true);

        } else {
            this.noWalrusesLabel.setVisible(false);
            this.grid.clear();
            this.grid.resize(this.walrusList.size(), 1);
            this.grid.setVisible(true);
            this.grid.setStyleName("euca-table");
            this.grid.setCellPadding(2);

            int row = 0;
            for (WalrusInfoWeb w : this.walrusList) {
                /*// big yellow block looks kinda weird
                if ( ( row % 2 ) == 1 ) {
                   this.grid.getRowFormatter().setStyleName( row, "euca-table-even-row" );
                } else {
                   this.grid.getRowFormatter().setStyleName( row, "euca-table-odd-row" );
                }*/
                this.grid.setWidget(row, 0, addWalrusEntry(row++, w));
            }

            if (row >= maxWalruses) {
                this.add_button.setEnabled(false);
            } else {
                this.add_button.setEnabled(true);
            }
        }
    }

    private Grid addWalrusEntry(int row, WalrusInfoWeb walrusInfo) {
        final ArrayList<String> properties = walrusInfo.getProperties();
        int numProperties = properties.size() / 4;
        Grid g = new Grid(1 + numProperties, 2);
        g.setStyleName("euca-table");
        g.setCellPadding(4);

        int i = 0; // row 1
        g.setWidget(i, 0, new Label("Walrus host:"));
        g.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT);
        HorizontalPanel p = new HorizontalPanel();
        p.setSpacing(0);
        g.setWidget(i, 1, p);
        final TextBox walrusHost_box = new TextBox();
        walrusHost_box.addChangeListener(new ChangeCallback(this, row));
        walrusHost_box.setVisibleLength(35);
        walrusHost_box.setText(walrusInfo.getHost());
        p.add(walrusHost_box);
        p.add(new EucaButton("Deregister", new DeleteCallback(this, row)));

        for (int propIdx = 0; propIdx < numProperties; ++propIdx) {
            i++; // next row
            if ("KEYVALUE".equals(properties.get(4 * propIdx))) {
                g.setWidget(i, 0, new Label(properties.get(4 * propIdx + 1) + ": "));
                g.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT);
                final TextBox propTextBox = new TextBox();
                propTextBox.addChangeListener(new ChangeCallback(this, row));
                propTextBox.setVisibleLength(30);
                propTextBox.setText(properties.get(4 * propIdx + 2));
                propTextBox.addFocusListener(new FocusHandler(this.hint, this.warningMessage));
                g.setWidget(i, 1, propTextBox);
            } else if ("KEYVALUEHIDDEN".equals(properties.get(4 * propIdx))) {
                g.setWidget(i, 0, new Label(properties.get(4 * propIdx + 1) + ": "));
                g.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT);
                final TextBox propTextBox = new PasswordTextBox();
                propTextBox.addChangeListener(new ChangeCallback(this, row));
                propTextBox.setVisibleLength(30);
                propTextBox.setText(properties.get(4 * propIdx + 2));
                propTextBox.addFocusListener(new FocusHandler(this.hint, this.warningMessage));
                g.setWidget(i, 1, propTextBox);
            } else if ("BOOLEAN".equals(properties.get(4 * propIdx))) {
                final int index = propIdx;
                final CheckBox propCheckbox = new CheckBox();
                g.getCellFormatter().setHorizontalAlignment(i, 0, HasHorizontalAlignment.ALIGN_RIGHT);
                g.setWidget(i, 0, propCheckbox);
                if (Boolean.parseBoolean(properties.get(4 * index + 2))) {
                    propCheckbox.setChecked(true);
                } else {
                    propCheckbox.setChecked(false);
                }
                propCheckbox.addClickListener(new ClickListener() {
                    public void onClick(Widget sender) {
                        if (((CheckBox) sender).isChecked()) {
                            properties.set(4 * index + 2, String.valueOf(true));
                        } else {
                            properties.set(4 * index + 2, String.valueOf(false));
                        }
                    }
                });
                g.setWidget(i, 1, new Label(properties.get(propIdx * 4 + 1)));
            }
        }
        return g;
    }

    public List<WalrusInfoWeb> getWalrusList() {
        return walrusList;
    }

    public void setWalrusList(final List<WalrusInfoWeb> walrusList) {
        this.walrusList = walrusList;
    }

    public void updateRow(int row) {
        WalrusInfoWeb walrus = this.walrusList.get(row);
        Grid g = (Grid) this.grid.getWidget(row, 0);
        HorizontalPanel p = (HorizontalPanel) g.getWidget(0, 1);
        walrus.setHost(((TextBox) p.getWidget(0)).getText());
        int widgetStartIndex = 1;
        ArrayList<String> properties = walrus.getProperties();
        for (int i = 0; i < (properties.size() / 4); ++i) {
            if (properties.get(4 * i).startsWith("KEYVALUE"))
                properties.set(4 * i + 2, ((TextBox) g.getWidget(widgetStartIndex + i, 1)).getText());
        }
    }

    public void MarkCommitted() {
        for (WalrusInfoWeb walrus : this.walrusList) {
            walrus.setCommitted();
        }
    }

    class ChangeCallback implements ChangeListener, ClickListener {
        private WalrusInfoTable parent;
        private int row;

        ChangeCallback(final WalrusInfoTable parent, final int row) {
            this.parent = parent;
            this.row = row;
        }

        public void onChange(Widget sender) {
            this.parent.updateRow(this.row);
            this.parent.statusLabel.setText("Unsaved changes");
            this.parent.statusLabel.setStyleName("euca-greeting-warning");
        }

        public void onClick(Widget sender) {
            this.parent.updateRow(this.row);
            this.parent.statusLabel.setText("Unsaved changes");
            this.parent.statusLabel.setStyleName("euca-greeting-warning");
        }
    }

    class DeleteCallback implements ClickHandler {

        private WalrusInfoTable parent;
        private int row;

        DeleteCallback(final WalrusInfoTable parent, final int row) {
            this.parent = parent;
            this.row = row;
        }

        public void onClick(ClickEvent event) {
            this.parent.walrusList.remove(this.row);
            this.parent.rebuildTable();
            this.parent.statusLabel.setText("Unsaved changes");
            this.parent.statusLabel.setStyleName("euca-greeting-warning");
        }
    }

    class GetWalrusListCallback implements AsyncCallback {

        private WalrusInfoTable parent;

        GetWalrusListCallback(final WalrusInfoTable parent) {
            this.parent = parent;
        }

        public void onFailure(final Throwable throwable) {
            this.parent.statusLabel.setText("Failed to contact server!");
            this.parent.statusLabel.setStyleName("euca-greeting-error");
        }

        public void onSuccess(final Object o) {
            List<WalrusInfoWeb> newWalrusList = (List<WalrusInfoWeb>) o;
            this.parent.statusLabel.setText("Walrus configuration up to date");
            this.parent.statusLabel.setStyleName("euca-greeting-disabled");
            this.parent.walrusList = newWalrusList;
            this.parent.MarkCommitted();
            this.parent.rebuildTable();
        }
    }

    class SaveCallback implements AsyncCallback, ClickHandler {

        private WalrusInfoTable parent;

        SaveCallback(final WalrusInfoTable parent) {
            this.parent = parent;
        }

        public void onClick(ClickEvent event) {
            this.parent.statusLabel.setText("Saving...");
            this.parent.statusLabel.setStyleName("euca-greeting-pending");
            EucalyptusWebBackend.App.getInstance().setWalrusList(this.parent.sessionId, this.parent.walrusList,
                    this);
        }

        public void onFailure(final Throwable throwable) {
            this.parent.statusLabel.setText("Failed to save! (Check hostname and path.)");
            this.parent.statusLabel.setStyleName("euca-greeting-error");
        }

        public void onSuccess(final Object o) {
            this.parent.statusLabel.setText("Saved Walrus configuration to server");
            this.parent.statusLabel.setStyleName("euca-greeting-disabled");
            this.parent.MarkCommitted();
            this.parent.rebuildTable(); // so the committed ones show up
        }
    }

    class FocusHandler implements FocusListener {
        private HTML parent;
        private String message;

        FocusHandler(final HTML parent, String message) {
            this.parent = parent;
            this.message = message;
        }

        public void onLostFocus(Widget sender) {
            this.parent.setHTML("");
            this.parent.setStyleName("euca-text");
        }

        public void onFocus(Widget sender) {
            this.parent.setHTML(message);
            this.parent.setStyleName("euca-error-hint");
        }
    }
}