org.opendatakit.aggregate.client.table.OdkTablesViewTable.java Source code

Java tutorial

Introduction

Here is the source code for org.opendatakit.aggregate.client.table.OdkTablesViewTable.java

Source

/*
 * Copyright (C) 2013 University of Washington
 *
 * 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.
 */

package org.opendatakit.aggregate.client.table;

import java.util.ArrayList;

import org.opendatakit.aggregate.client.AggregateSubTabBase;
import org.opendatakit.aggregate.client.AggregateUI;
import org.opendatakit.aggregate.client.OdkTablesViewTableSubTab;
import org.opendatakit.aggregate.client.SecureGWT;
import org.opendatakit.aggregate.client.exception.EntityNotFoundExceptionClient;
import org.opendatakit.aggregate.client.exception.PermissionDeniedExceptionClient;
import org.opendatakit.aggregate.client.odktables.RowClient;
import org.opendatakit.aggregate.client.odktables.TableContentsClient;
import org.opendatakit.aggregate.client.odktables.TableEntryClient;
import org.opendatakit.aggregate.client.widgets.OdkTablesDeleteRowButton;
import org.opendatakit.aggregate.constants.common.SubTabs;
import org.opendatakit.common.security.common.GrantedAuthorityName;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;

/**
 * Displays the contents of a table.
 *
 * @author sudar.sam@gmail.com
 *
 */
public class OdkTablesViewTable extends FlexTable {

    // the table that we are currently displaying.
    private TableEntryClient currentTable;

    // that table's rows
    private ArrayList<RowClient> rows;

    // that table's column names
    private ArrayList<String> columnNames;

    // this is the heading for the delete row button.
    private static final String DELETE_ROW_HEADING = "Delete";

    // these are far right
    private static final String SAVEPOINT_TYPE = "Status";
    private static final String FORM_ID = "Form Id";
    private static final String LOCALE = "Locale";
    private static final String SAVEPOINT_TIMESTAMP = "Last Updated At";
    private static final String SAVEPOINT_CREATOR = "Last Updated By";
    private static final String ROW_ID = "Row ID";
    private static final String ROW_ETAG = "Row ETag";
    private static final String FILTER_TYPE = "Filter Type";
    private static final String FILTER_VALUE = "Filter Value";

    private AggregateSubTabBase tableSubTab;

    // this is the number of columns that exist for a table as returned
    // by the server that are NOT user defined.
    private static final int NUMBER_ADMIN_COLUMNS = 10;

    // the message to display when there is no data in the table.
    private static String NO_DATA_MESSAGE = "There is no data in this table.";
    // the message to display when there are no rows in the table
    private static String NO_ROWS_MESSAGE = "There are no rows to display.";

    /**
     * This is the constructor to call when there has not been a table selected.
     * Should this even exist?
     */
    public OdkTablesViewTable(AggregateSubTabBase tableSubTab) {
        // add styling
        addStyleName("dataTable");
        getElement().setId("form_management_table");

        this.tableSubTab = tableSubTab;

        // no current table.
        this.currentTable = null;
    }

    public OdkTablesViewTable(AggregateSubTabBase tableSubTab, TableEntryClient table) {
        this(tableSubTab);

        updateDisplay(table);

        this.currentTable = table;
    }

    /**
     * This updates the display to show the contents of the table.
     */
    public void updateDisplay(TableEntryClient table) {
        @SuppressWarnings("unused")
        TableEntryClient oldTable = this.currentTable;

        // for testing timing
        // Window.alert("in odktablesViewTable.updateDisplay()");

        this.currentTable = table;

        if (table == null) {
            this.removeAllRows();
        } else {

            /*** update the data ***/
            updateData(table);
        }

    }

    public void updateData(TableEntryClient table) {
        // set up the callback object
        AsyncCallback<TableContentsClient> getDataCallback = new AsyncCallback<TableContentsClient>() {
            @Override
            public void onFailure(Throwable caught) {
                if (caught instanceof EntityNotFoundExceptionClient) {
                    // if this happens it is PROBABLY, but not necessarily, because
                    // we've deleted the table.
                    // TODO ensure the correct exception makes it here
                    ((OdkTablesViewTableSubTab) AggregateUI.getUI().getSubTab(SubTabs.VIEWTABLE))
                            .setTabToDisplayZero();
                } else if (caught instanceof PermissionDeniedExceptionClient) {
                    // do nothing, b/c it's probably legitimate that you don't get an
                    // error if there are rows you're not allowed to see.

                } else {
                    AggregateUI.getUI().reportError(caught);
                }
            }

            @Override
            public void onSuccess(TableContentsClient tcc) {
                columnNames = tcc.columnNames;
                setColumnHeadings(columnNames);

                rows = tcc.rows;
                setRows(rows);

            }
        };
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        // TODO: paginate this
        if (AggregateUI.getUI().getUserInfo().getGrantedAuthorities()
                .contains(GrantedAuthorityName.ROLE_SYNCHRONIZE_TABLES)) {
            SecureGWT.getServerDataService().getTableContents(table.getTableId(), getDataCallback);
        }
    }

    /*
     * public void updateRows(TableEntryClient table) { // set up the callback
     * object AsyncCallback<List<RowClient>> getRowsCallback = new
     * AsyncCallback<List<RowClient>>() {
     *
     * @Override public void onFailure(Throwable caught) {
     * AggregateUI.getUI().reportError(caught); }
     *
     * @Override public void onSuccess(List<RowClient> rowList) { rows = rowList;
     * setRows(rows);
     *
     * AggregateUI.getUI().getTimer().refreshNow();
     *
     * } };
     *
     * // otherwise, we need to get the data.
     * SecureGWT.getServerDataService().getRows(table.getTableId(),
     * getRowsCallback); }
     *
     * /** updates the column names.
     *
     * @param table
     *
     * public void updateColumns(TableEntryClient table) {
     *
     * AsyncCallback<List<String>> columnNamesCallback = new
     * AsyncCallback<List<String>>() {
     *
     * @Override public void onFailure(Throwable caught) {
     * AggregateUI.getUI().reportError(caught); }
     *
     * @Override public void onSuccess(List<String> columns) { columnNames =
     * columns; setColumnHeadings(columns);
     *
     * AggregateUI.getUI().getTimer().refreshNow();
     *
     * }
     *
     *
     * };
     *
     *
     * SecureGWT.getServerDataService().getColumnNames(table.getTableId(),
     * columnNamesCallback);
     *
     * }
     */

    /**
     * This is the method that actually updates the column headings. It is its
     * own method so that it can be called cleanly in the updateTableData method.
     * If the code is AFTER the call to SecureGWT, as it was at first, you can
     * get null pointer exceptions, as the async callback may have not returned.
     */
    private void setColumnHeadings(ArrayList<String> columns) {
        this.removeAllRows();

        // If there are no user-defined columns display the message.
        // Otherwise set the headings.
        if (columns.size() == 0) {
            setText(0, 0, NO_DATA_MESSAGE);
        } else {
            // set the delete column
            setText(0, 0, DELETE_ROW_HEADING);
            int i = 1;
            // make the headings
            for (String name : this.columnNames) {
                // We might have to do checking eventually to ensure metadata columns
                // are only displayed when necessary.
                setText(0, i, name);
                i++;
            }
            setText(0, i++, SAVEPOINT_TYPE);
            setText(0, i++, FORM_ID);
            setText(0, i++, LOCALE);
            setText(0, i++, SAVEPOINT_TIMESTAMP);
            setText(0, i++, SAVEPOINT_CREATOR);
            setText(0, i++, ROW_ID);
            setText(0, i++, ROW_ETAG);
            setText(0, i++, FILTER_TYPE);
            setText(0, i++, FILTER_VALUE);

            getRowFormatter().addStyleName(0, "titleBar");
        }

    }

    /*
     * This will set the row values in the listbox.
     */
    private void setRows(ArrayList<RowClient> rows) {
        int start = 1; // b/c the 0 row is the headings.

        int currentRow = start;

        // if there are no columns, then we only want to display the no data
        // message.
        if (columnNames.size() == 0) {
            return;
            // otherwise check if there are no rows.
        } else if (rows.size() == 0) {
            setWidget(currentRow, 0, new HTML(NO_ROWS_MESSAGE));
            // make the display fill all the columns you have. this is the total
            // number of
            // user-defined columns +1 for the delete column.
            this.getFlexCellFormatter().setColSpan(start + currentRow, 0,
                    columnNames.size() + NUMBER_ADMIN_COLUMNS);
        } else { // there are rows--display them.

            for (RowClient row : rows) {
                // the rows that come through beginning with "_" are user-defined.
                // we only want to display those (as long as you're not displaying
                // metadata), so select those, remove them, and add them.
                // i is counter, j is columns. fill row by moving to the right, then
                // move on
                // currentRow is the actual current row. this is different than the
                // counter, b/c
                // you can also get deleted rows returned.

                // don't display deleted rows (although the dm doesn't return them at
                // this point)
                if (!row.isDeleted()) {
                    // now set the delete button
                    OdkTablesDeleteRowButton deleteButton = new OdkTablesDeleteRowButton(this,
                            currentTable.getTableId(), row.getRowId(), row.getRowETag());
                    if (!AggregateUI.getUI().getUserInfo().getGrantedAuthorities()
                            .contains(GrantedAuthorityName.ROLE_ADMINISTER_TABLES)) {
                        deleteButton.setEnabled(false);
                    }
                    setWidget(currentRow, 0, deleteButton);
                    int j = 1;
                    for (String column : columnNames) {
                        setWidget(currentRow, j, new HTML(row.getValues().get(column)));
                        j++;
                    }
                    setWidget(currentRow, j++, new HTML(row.getSavepointType()));
                    setWidget(currentRow, j++, new HTML(row.getFormId()));
                    setWidget(currentRow, j++, new HTML(row.getLocale()));
                    setWidget(currentRow, j++, new HTML(row.getSavepointTimestampIso8601Date()));
                    setWidget(currentRow, j++, new HTML(row.getSavepointCreator()));
                    setWidget(currentRow, j++, new HTML(row.getRowId()));
                    setWidget(currentRow, j++, new HTML(row.getRowETag()));
                    setWidget(currentRow, j++, new HTML(row.getFilterScope().getType().name()));
                    setWidget(currentRow, j++, new HTML(row.getFilterScope().getValue()));

                    if (currentRow % 2 == 0) {
                        getRowFormatter().addStyleName(currentRow, "evenTableRow");
                    }
                }
                currentRow++;
            }
        }
    }

    /**
     * Returns the view this table is currently displaying.
     */
    public TableEntryClient getCurrentTable() {
        return currentTable;
    }

}