TaskListPresenter.java Source code

Java tutorial

Introduction

Here is the source code for TaskListPresenter.java

Source

/*******************************************************************************
 * Copyright (c) 2010, 2012 Tasktop Technologies
 * Copyright (c) 2010, 2011 SpringSource, a division of VMware
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 ******************************************************************************/
//package com.tasktop.c2c.server.tasks.client.presenters; new line

import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent.AsyncHandler;
import com.google.gwt.user.cellview.client.ColumnSortList.ColumnSortInfo;
import com.google.gwt.user.cellview.client.RowStyles;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.NoSelectionModel;
import com.google.gwt.view.client.Range;
import com.tasktop.c2c.server.common.profile.web.client.AuthenticationHelper;
import com.tasktop.c2c.server.common.profile.web.client.ProfileGinjector;
import com.tasktop.c2c.server.common.service.domain.QueryRequest;
import com.tasktop.c2c.server.common.service.domain.QueryResult;
import com.tasktop.c2c.server.common.service.domain.Region;
import com.tasktop.c2c.server.common.service.domain.SortInfo;
import com.tasktop.c2c.server.common.service.domain.SortInfo.Order;
import com.tasktop.c2c.server.common.web.client.navigation.Navigation;
import com.tasktop.c2c.server.common.web.client.notification.Message;
import com.tasktop.c2c.server.common.web.client.notification.Message.MessageType;
import com.tasktop.c2c.server.common.web.client.presenter.AsyncCallbackSupport;
import com.tasktop.c2c.server.common.web.client.view.CellTableResources;
import com.tasktop.c2c.server.tasks.client.place.ProjectNewTaskPlace;
import com.tasktop.c2c.server.tasks.client.place.ProjectTasksPlace;
import com.tasktop.c2c.server.tasks.client.widgets.TaskListView;
import com.tasktop.c2c.server.tasks.client.widgets.tasklist.TaskColumnDescriptor;
import com.tasktop.c2c.server.tasks.client.widgets.tasklist.TaskListColumnConfiguration;
import com.tasktop.c2c.server.tasks.domain.PredefinedTaskQuery;
import com.tasktop.c2c.server.tasks.domain.SavedTaskQuery;
import com.tasktop.c2c.server.tasks.domain.Task;
import com.tasktop.c2c.server.tasks.shared.QueryState;
import com.tasktop.c2c.server.tasks.shared.action.TaskQueryAction;
import com.tasktop.c2c.server.tasks.shared.action.TaskQueryResult;

/**
 * a presenter for showing a list of tasks, usually used to show task search results.
 */
public class TaskListPresenter extends AbstractTaskPresenter {

    private final TaskListView taskListView;

    private CellTable<Task> resultsTable;
    private AsyncDataProvider<Task> dataProvider;
    private MultiSelectionModel<Task> selectionModel;
    private QueryState queryState;

    private String taskServiceBaseUrl;

    private TaskListColumnConfiguration taskListColumnConfiguration;

    public TaskListPresenter(TaskListView view, TasksPresenter parentPresenter) {
        super(view);
        taskListView = view;
        view.setPresenter(parentPresenter);
    }

    @Override
    public void setProjectIdentifier(String projectId) {
        super.setProjectIdentifier(projectId);
        String path = Window.Location.getPath();
        String appCtx = path.substring(0, path.lastIndexOf("/"));
        taskServiceBaseUrl = appCtx + "/s/" + projectIdentifier + "/tasks/";
    }

    @Override
    protected void bind() {
        // If this user is anonymous, then hide options and features which are only available to logged-in users.
        if (!AuthenticationHelper.isAnonymous()) {
            setupNewTaskButton();
        }
        initializeResultsTable();
    }

    private void setupNewTaskButton() {
        taskListView.newTask.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                ProjectNewTaskPlace.createNewTaskPlace(projectIdentifier).go();
            }
        });
    }

    public void doSearch(QueryState queryState) {
        this.queryState = queryState;
        startNewSearch();

        switch (queryState.getQueryType()) {
        case Criteria:
            doSearchWithCriteria(queryState.getQueryString());
            break;
        case Predefined:
            doSearch(queryState.getPredefinedQuery());
            break;
        case Saved:
            doSearch(queryState.getSavedQuery());
            break;
        case Text:
            doSearch(queryState.getQueryString());
            break;
        default:
            throw new IllegalStateException("Illegal query type: " + queryState.getQueryType());
        }
    }

    private void doSearch(String text) {
        taskListView.exportCsvAnchor.setHref(taskServiceBaseUrl + "export/text/csv/" + text);
        taskListView.exportJsonAnchor.setHref(taskServiceBaseUrl + "export/text/json/" + text);
        taskListView.updateLabel(text);
    }

    private void doSearch(PredefinedTaskQuery query) {
        taskListView.exportCsvAnchor.setHref(taskServiceBaseUrl + "export/predefined/csv/" + query.name());
        taskListView.exportJsonAnchor.setHref(taskServiceBaseUrl + "export/predefined/json/" + query.name());
        taskListView.clearSearchInfo();
    }

    private void doSearch(SavedTaskQuery query) {
        doSearchWithCriteria(query.getQueryString());
        taskListView.updateLabel(query);
    }

    private void doSearchWithCriteria(String criteria) {
        taskListView.exportCsvAnchor.setHref(taskServiceBaseUrl + "export/criteria/csv/" + criteria);
        taskListView.exportJsonAnchor.setHref(taskServiceBaseUrl + "export/criteria/json/" + criteria);
        taskListView.updateLabel(criteria);
    }

    // REVIEW : this should be in the view.
    private void initializeResultsTable() {
        if (resultsTable != null) {
            return;
        }
        resultsTable = new CellTable<Task>(15, CellTableResources.get.resources);
        resultsTable.setSelectionModel(new NoSelectionModel<Task>());
        resultsTable.setPageSize(ProjectTasksPlace.DEFAULT_PAGESIZE);
        resultsTable.setStyleName("tasks");
        resultsTable.setRowStyles(new RowStyles<Task>() {
            public String getStyleNames(Task row, int rowIndex) {
                if (row.getStatus().getValue().equals("NEW")) {
                    return "new";
                }
                return null;
            }
        });

        taskListView.pager.setDisplay(resultsTable);

        taskListColumnConfiguration = new TaskListColumnConfiguration(this, resultsTable, selectionModel);
        taskListColumnConfiguration.configureFromRequest();
        taskListColumnConfiguration.apply();
        taskListView.tasksPanel.add(resultsTable);

    }

    private void startNewSearch() {
        initializeViewAdapter();

        int indexStart = queryState.getQueryRequest().getPageInfo().getOffset();
        int resultSize = queryState.getQueryRequest().getPageInfo().getSize();
        resultsTable.getColumnSortList().clear();
        if (queryState.getQueryRequest().getSortInfo() != null) {
            Column<?, ?> column = getColumnSortInfo(queryState.getQueryRequest().getSortInfo());
            if (column != null) {
                ColumnSortInfo csi = new ColumnSortInfo(column,
                        queryState.getQueryRequest().getSortInfo().getSortOrder().equals(Order.ASCENDING));
                resultsTable.getColumnSortList().push(csi);
            } else {
                ProfileGinjector.get.instance().getNotifier()
                        .displayMessage(new Message(10, "Unknown sort", MessageType.ERROR));
            }
        }
        // This will trigger a call to fetchRange()
        resultsTable.setVisibleRangeAndClearData(new Range(indexStart, resultSize), true);
    }

    private void initializeViewAdapter() {
        if (dataProvider == null) {
            // use a local variable so that initialization doesn't cause a refresh.
            AsyncDataProvider<Task> dataProvider = new AsyncDataProvider<Task>() {
                @Override
                protected void onRangeChanged(HasData<Task> view) {
                    if (TaskListPresenter.this.dataProvider == null) {
                        return;
                    }
                    fetchRange(view.getVisibleRange());
                }
            };
            dataProvider.addDataDisplay(resultsTable);
            AsyncHandler columnSortHandler = new AsyncHandler(resultsTable);
            resultsTable.addColumnSortHandler(columnSortHandler);

            this.dataProvider = dataProvider;
        }
    }

    protected void fetchRange(final Range range) {
        QueryRequest request = new QueryRequest();
        request.setPageInfo(new Region(range.getStart(), range.getLength()));
        SortInfo sortInfo = getSortInfoFromTable();
        if (sortInfo != null && sortInfo.getSortField() != null && sortInfo.getSortOrder() != null) {
            request.setSortInfo(sortInfo);
        }

        queryState.setQueryRequest(request);
        // Update the current URL to represent the new page and sort parameters
        updateCurrentUrlForQuery(request);

        final AsyncCallbackSupport<TaskQueryResult> callback = new AsyncCallbackSupport<TaskQueryResult>() {

            @Override
            protected void success(TaskQueryResult actionResult) {
                QueryResult<Task> result = actionResult.get();
                // TODO: when range starts at 0 and no results found, hide
                // results table and show 'no results found' message
                dataProvider.updateRowCount(result.getTotalResultSize(), true);
                // set the length to less than one page when necessary
                dataProvider.updateRowData(range.getStart(), result.getResultPage());
            }

            @Override
            public void onFailure(Throwable exception) {
                super.onFailure(exception);
                dataProvider.updateRowCount(0, false);
            }
        };

        TaskQueryAction action = new TaskQueryAction(getProjectIdentifier(), queryState);
        getDispatchService().execute(action, callback);
    }

    private SortInfo getSortInfoFromTable() {
        if (resultsTable.getColumnSortList().size() == 0) {
            return null;
        }
        ColumnSortInfo sort = resultsTable.getColumnSortList().get(0);
        String fieldId = taskListColumnConfiguration.getDescriptor(sort.getColumn()).getTaskField();
        return new SortInfo(fieldId, sort.isAscending() ? Order.ASCENDING : Order.DESCENDING);
    }

    private Column<?, ?> getColumnSortInfo(SortInfo sortInfo) {
        TaskColumnDescriptor descriptor = taskListColumnConfiguration.getDescriptorById(sortInfo.getSortField());
        if (descriptor == null) {
            return null;
        }
        return descriptor.getColumn();
    }

    private void updateCurrentUrlForQuery(QueryRequest request) {
        // FIXME / TODO use the logic in ProjectTasksPlace.
        // Get our current page URL

        SortInfo sortInfo = request.getSortInfo();
        // Get our current parameters.
        Map<String, List<String>> urlParamMap = Navigation.getNavigationParameterMap();

        // Append our parameters as appropriate
        if (sortInfo != null) {
            updateParamInMap(urlParamMap, ProjectTasksPlace.SORTFIELD_URLPARAM, sortInfo.getSortField(),
                    sortInfo.getSortField() != null);
            updateParamInMap(urlParamMap, ProjectTasksPlace.SORTORDER_URLPARAM,
                    String.valueOf(sortInfo.getSortOrder()), sortInfo.getSortOrder() != null);
        }

        Region requestRegion = request.getPageInfo();
        updateParamInMap(urlParamMap, ProjectTasksPlace.NUMRESULTS_URLPARAM,
                String.valueOf(requestRegion.getSize()),
                requestRegion.getSize() != ProjectTasksPlace.DEFAULT_PAGESIZE);
        updateParamInMap(urlParamMap, ProjectTasksPlace.STARTINDEX_URLPARAM,
                String.valueOf(requestRegion.getOffset()), requestRegion.getOffset() > 0);

        String updatedUrl = History.getToken();

        // Strip off the set of URL parameters on the current history token if they exist.
        if (updatedUrl.indexOf('?') > 0) {
            updatedUrl = updatedUrl.substring(0, updatedUrl.indexOf('?'));
        }

        // Now, loop through and write all of our parameters to our URL.
        for (String curParamName : urlParamMap.keySet()) {
            for (String curParamValue : urlParamMap.get(curParamName)) {
                updatedUrl = Navigation.appendQueryParameterToUrl(updatedUrl, curParamName, curParamValue);
            }
        }

        // Update our URL, but don't trigger a page navigation - it's already in progress.
        History.newItem(updatedUrl, false);
    }

    private void updateParamInMap(Map<String, List<String>> paramMap, String paramName, String paramValue,
            boolean conditionMet) {
        // First, clear any existing value
        paramMap.remove(paramName);

        // Then, plug in our value if appropriate
        if (conditionMet) {
            paramMap.put(paramName, Collections.singletonList(paramValue));
        }
    }

    /**
     * 
     */
    public void onQuerySaved() {
        taskListView.saveSuccess();
    }
}