org.apache.oozie.tools.workflowgenerator.client.property.PropertyTable.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.oozie.tools.workflowgenerator.client.property.PropertyTable.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

package org.apache.oozie.tools.workflowgenerator.client.property;

import java.util.ArrayList;
import java.util.List;
import org.apache.oozie.tools.workflowgenerator.client.OozieDiagramController;
import org.apache.oozie.tools.workflowgenerator.client.widget.NodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.EmailActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.FSActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.JavaActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.MapReduceActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.PigActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.PipesActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.SSHActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.ShellActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.StreamingActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.action.SubWFActionWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.DecisionNodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.EndNodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.ForkNodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.JoinNodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.KillNodeWidget;
import org.apache.oozie.tools.workflowgenerator.client.widget.control.StartNodeWidget;
import com.google.gwt.cell.client.ButtonCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.SelectionCell;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Text;

/**
 * Base abstract class for property table;
 */
public abstract class PropertyTable extends ScrollPanel {

    protected NodeWidget current;
    protected TextBox name;
    protected ListBox okVal;
    protected ListBox errorVal;
    protected TextBox jt;
    protected TextBox nn;
    protected List<NodeWidget> widgetDropDown;
    protected HandlerRegistration handler;
    protected Grid grid;

    /**
     * Constructor which records node widget
     *
     * @param w node widget
     */
    public PropertyTable(NodeWidget w) {
        super();
        this.current = w;
    }

    /**
     * Update a list of other node widgets shown in "OK" drop-down, excluding
     * start and kill nodes
     */
    public void updateWidgetDropDown() {

        List<NodeWidget> widgetList = current.getGenerator().getWidgets();
        OozieDiagramController controller = current.getController();

        if (widgetDropDown == null) {
            widgetDropDown = new ArrayList<NodeWidget>();
        } else {
            widgetDropDown.clear();
        }

        if (widgetList != null) {
            for (NodeWidget w : widgetList) {
                if (!(w instanceof KillNodeWidget) && !(w instanceof StartNodeWidget) && w != current) {
                    widgetDropDown.add(w);
                }
            }
        }

        // if okVal listbox doesn't exist, return
        if (okVal != null) {
            okVal.clear();
        } else {
            return;
        }
        // insert empty option on top
        okVal.addItem("");

        for (int i = 0; i < widgetDropDown.size(); i++) {
            NodeWidget w = widgetDropDown.get(i);
            okVal.addItem(prettyItemString(w));
            // option selected when this node widget is connected to the
            // widget in a design panel
            List<NodeWidget> neigh = controller.getCurrentNeighbor(current);
            if (neigh != null && neigh.size() > 0 && w == neigh.get(0))
                okVal.setSelectedIndex(i + 1);
        }

        // remove previous handler, otherwise, end up having multiple handlers
        if (handler != null) {
            handler.removeHandler();
        }

        handler = okVal.addChangeHandler(new ChangeHandler() {
            @Override
            public void onChange(ChangeEvent event) {
                int selectedIndex = okVal.getSelectedIndex();
                if (selectedIndex > 0) {
                    NodeWidget target = widgetDropDown.get(selectedIndex - 1);
                    current.getController().addConnection(current, target);
                }

            }
        });
    }

    /**
     * Update "Error" drop-down list, currently only includes default kill node
     */
    public void updateErrorDropDown() {

        List<NodeWidget> widgetList = current.getGenerator().getWidgets();

        if (errorVal == null) {
            errorVal = new ListBox();
        } else {
            errorVal.clear();
        }

        for (NodeWidget w : widgetList) {
            if (w instanceof KillNodeWidget) {
                errorVal.addItem(prettyItemString(w));
                errorVal.setSelectedIndex(0);
            }
        }
    }

    /**
     * Return an instance of a kill node
     *
     * @return
     */
    protected NodeWidget getKillNode() {

        List<NodeWidget> widgetList = current.getGenerator().getWidgets();
        NodeWidget node = null;
        for (NodeWidget w : widgetList) {
            if (w instanceof KillNodeWidget)
                node = w;
        }
        return node;
    }

    /**
     * Abstract method to generate xml elements and attach them to xml doc
     *
     * @param doc xml document
     * @param root xml element under which generated xml elements are added
     * @param next next node widget to be executed after this in workflow
     */
    public abstract void generateXML(Document doc, Element root, NodeWidget next);

    /**
     * Append a type of the node widget to its name for readability
     *
     * @param w
     * @return
     */
    protected String prettyItemString(NodeWidget w) {
        StringBuilder s = new StringBuilder();
        s.append(w.getName());
        s.append(" ");
        if (w instanceof EndNodeWidget) {
            s.append(" (End Node)");
        } else if (w instanceof ForkNodeWidget) {
            s.append(" (Fork Node)");
        } else if (w instanceof JoinNodeWidget) {
            s.append(" (Join Node)");
        } else if (w instanceof MapReduceActionWidget) {
            s.append(" (MR Action)");
        } else if (w instanceof PigActionWidget) {
            s.append(" (Pig Action)");
        } else if (w instanceof StreamingActionWidget) {
            s.append(" (MR Streaming Action)");
        } else if (w instanceof PipesActionWidget) {
            s.append(" (MR Pipes Action)");
        } else if (w instanceof JavaActionWidget) {
            s.append(" (Java Action)");
        } else if (w instanceof FSActionWidget) {
            s.append(" (FS Action)");
        } else if (w instanceof DecisionNodeWidget) {
            s.append(" (Decision Node)");
        } else if (w instanceof KillNodeWidget) {
            s.append(" (Kill Node)");
        } else if (w instanceof SSHActionWidget) {
            s.append(" (SSH Node)");
        } else if (w instanceof SubWFActionWidget) {
            s.append(" (SubWF Node)");
        } else if (w instanceof EmailActionWidget) {
            s.append(" (Email Node)");
        } else if (w instanceof ShellActionWidget) {
            s.append(" (Shell Node)");
        }
        return s.toString();
    }

    /**
     * Set the width of widget
     *
     * @param w widget
     * @return
     */
    protected Widget formatCell(Widget w) {
        w.setWidth("300px");
        return w;
    }

    /**
     * Create an expandable sub table as a part of property table
     *
     * @param colname1 1st column name
     * @param colname2 2nd column name
     * @param data data list
     * @param options listbox options, if null, text input cell used
     * @return
     */
    protected CellTable<Property> createSubTable(String colname1, String colname2, List<Property> data,
            List<String> options) {

        final CellTable<Property> table = new CellTable<Property>();
        final ListDataProvider<Property> dataProvider = new ListDataProvider<Property>();
        dataProvider.setList(data);
        dataProvider.addDataDisplay(table);

        // add Name column
        Column<Property, String> nameCol = null;

        if (options == null) {
            nameCol = new Column<Property, String>(new TextInputCell()) {
                @Override
                public String getValue(Property object) {
                    return object.getName();
                }
            };
        } else {
            nameCol = new Column<Property, String>(new SelectionCell(options)) {
                @Override
                public String getValue(Property object) {
                    return object.getName();
                }
            };
        }

        // set event for updating value
        nameCol.setFieldUpdater(new FieldUpdater<Property, String>() {
            @Override
            public void update(int index, Property object, String value) {
                object.setName(value);
            }
        });
        table.addColumn(nameCol, colname1);

        // Add Value column
        Column<Property, String> valueCol = new Column<Property, String>(new TextInputCell()) {
            @Override
            public String getValue(Property object) {
                return object.getValue();
            }
        };

        valueCol.setFieldUpdater(new FieldUpdater<Property, String>() {
            @Override
            public void update(int index, Property object, String value) {
                object.setValue(value);
            }
        });
        table.addColumn(valueCol, colname2);

        // Button to add row
        Column<Property, String> addCol = new Column<Property, String>(new ButtonCell()) {
            @Override
            public String getValue(Property object) {
                return " + ";
            }
        };
        addCol.setFieldUpdater(new FieldUpdater<Property, String>() {
            @Override
            public void update(int index, Property object, String value) {
                dataProvider.getList().add(index + 1, new Property("", ""));
            }
        });

        table.addColumn(addCol, "");

        // Button to delete row
        Column<Property, String> delCol = new Column<Property, String>(new ButtonCell()) {
            @Override
            public String getValue(Property object) {
                return " - ";
            }
        };

        delCol.setFieldUpdater(new FieldUpdater<Property, String>() {

            @Override
            public void update(int index, Property object, String value) {
                List<Property> li = dataProvider.getList();
                if (li.size() == 1) {
                    Property p = li.get(0);
                    p.setName("");
                    p.setValue("");
                    table.redraw();
                } else
                    dataProvider.getList().remove(index);
            }
        });

        table.addColumn(delCol, "");

        return table;
    }

    /**
     * Create an add button in a table
     *
     * @param table
     * @return
     */
    protected Button createAddButton(Grid table) {
        Button btn = new Button("+");
        btn.getElement().setAttribute("style",
                "font-size:20px;margin:0px;padding:0px;-webkit-border-radius:10px;-moz-border-radius:10px;-border-radius:10px;");
        return btn;
    }

    /**
     * create a delete button in a table
     *
     * @param table
     * @return
     */
    protected Button createDelButton(Grid table) {
        Button btn = new Button("-");
        btn.getElement().setAttribute("style",
                "font-size:20px;margin:0px;padding:0px;-webkit-border-radius:10px;-moz-border-radius:10px;-border-radius:10px;");
        return btn;
    }

    /**
     * Create a label with common format
     *
     * @param name
     * @return
     */
    protected Label createLabel(String name) {
        Label label = new Label(name);
        label.setWidth("100px");
        label.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
        return label;
    }

    /**
     * Generate xml elements of configuration
     *
     * @param list List of properties
     * @param root xml element under which configuration tag is added
     * @param doc xml document
     */
    protected void configToXML(List<Property> list, Element root, Document doc) {

        Element confEle = null;

        for (Property prop : list) {
            if (prop.getName() != null && !prop.getName().matches("\\s*") && prop.getValue() != null
                    && !prop.getValue().matches("\\s*")) {

                if (confEle == null) {
                    confEle = doc.createElement("configuration");
                    root.appendChild(confEle);
                }

                // create <property>
                Element propEle = doc.createElement("property");
                confEle.appendChild(propEle);

                // create <name>
                Element nameEle = doc.createElement("name");
                propEle.appendChild(nameEle);
                nameEle.appendChild(doc.createTextNode(prop.getName()));

                // create <value>
                Element valEle = doc.createElement("value");
                propEle.appendChild(valEle);
                valEle.appendChild(doc.createTextNode(prop.getValue()));
            }
        }

    }

    /**
     * Generate xml elements of prepare tag
     *
     * @param list list of properties
     * @param root xml element under which prepare tag is added
     * @param doc xml document
     */
    protected void prepareToXML(List<Property> list, Element root, Document doc) {

        Element prepareEle = null;
        for (Property prop : list) {
            if (prop.getName() != null && !prop.getName().matches("\\s*") && prop.getValue() != null
                    && !prop.getValue().matches("\\s*")) {

                if (prepareEle == null) {
                    prepareEle = doc.createElement("prepare");
                    root.appendChild(prepareEle);
                }

                // create <delete> or <mkdir>
                Element ele = null;
                if (prop.getName().equals("delete")) {
                    ele = doc.createElement("delete");
                } else if (prop.getName().equals("mkdir")) {
                    ele = doc.createElement("mkdir");
                }
                ele.setAttribute("path", prop.getValue());
                prepareEle.appendChild(ele);
            }
        }
    }

    /**
     * Generate xml elements of specified tag name
     *
     * @param list list of properties
     * @param root xml element under which new elements are added
     * @param doc xml document
     * @param key tag name
     */
    protected void filterListToXML(List<Property> list, Element root, Document doc, String key) {

        for (Property prop : list) {
            if (prop.getName() != null && !prop.getName().matches("\\s*") && prop.getValue() != null
                    && !prop.getValue().matches("\\s*")) {
                if (prop.getName().equals(key)) {
                    // create key element
                    Element nameEle = doc.createElement(key);
                    root.appendChild(nameEle);

                    // create text node under created element
                    Text valEle = doc.createTextNode(prop.getValue());
                    nameEle.appendChild(valEle);
                }
            }
        }
    }

    /**
     * Generate xml element of specific tag using content of textbox
     *
     * @param doc xml document
     * @param tag tag name
     * @param box textbox
     * @return
     */
    protected Element generateElement(Document doc, String tag, TextBox box) {
        Element ele = doc.createElement(tag);
        Text t = doc.createTextNode(box.getText());
        ele.appendChild(t);
        return ele;
    }

    /**
     * Generate xml element of ok
     *
     * @param doc xml document
     * @param next next node widget to be executed after this in workflow
     * @return
     */
    protected Element generateOKElement(Document doc, NodeWidget next) {
        Element okEle = doc.createElement("ok");
        okEle.setAttribute("to", next.getName());
        return okEle;
    }

    /**
     * Generate xml element of error
     *
     * @param doc xml document
     * @return
     */
    protected Element generateErrorElement(Document doc) {
        Element errEle = doc.createElement("error");
        NodeWidget kill = getKillNode();
        errEle.setAttribute("to", kill == null ? "" : kill.getName());
        return errEle;
    }

    /**
     * Insert a row with textbox into a grid table
     *
     * @param grid grid table
     * @param row row number
     * @param label name of label
     * @return
     */
    protected TextBox insertTextRow(Grid grid, int row, String label) {
        grid.setWidget(row, 0, createLabel(label));
        TextBox box = new TextBox();
        grid.setWidget(row, 1, formatCell(box));
        return box;
    }

    /**
     * Insert a row for ok into a grid table
     *
     * @param grid grid table
     * @param row row number
     */
    protected void insertOKRow(Grid grid, int row) {
        grid.setWidget(row, 0, createLabel("OK"));
        okVal = new ListBox();
        updateWidgetDropDown();
        grid.setWidget(row, 1, formatCell(okVal));
    }

    /**
     * Insert a row for error into a grid table
     *
     * @param grid grid table
     * @param row row number
     */
    protected void insertErrorRow(Grid grid, int row) {
        grid.setWidget(row, 0, createLabel("Error"));
        errorVal = new ListBox();
        updateErrorDropDown();
        grid.setWidget(row, 1, formatCell(errorVal));
    }

    /**
     * Return a name of the node widget
     *
     * @return
     */
    public String getName() {
        String n = null;
        if (name != null) {
            n = name.getText();
        } else {
            n = new String("");
        }
        return n;
    }

    /**
     * Set a name of the node widget
     *
     * @param n
     */
    public void setName(String n) {
        if (name != null) {
            name.setText(n);
        }
    }

}