com.tasktop.c2c.server.tasks.client.presenters.TaskSearchPresenter.java Source code

Java tutorial

Introduction

Here is the source code for com.tasktop.c2c.server.tasks.client.presenters.TaskSearchPresenter.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;

import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.TakesValue;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.SimpleCheckBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.DateBox;
import com.tasktop.c2c.server.common.profile.web.client.presenter.person.ProjectPersonService;
import com.tasktop.c2c.server.common.service.domain.criteria.ColumnCriteria;
import com.tasktop.c2c.server.common.service.domain.criteria.Criteria;
import com.tasktop.c2c.server.common.service.domain.criteria.Criteria.Operator;
import com.tasktop.c2c.server.common.service.domain.criteria.NaryCriteria;
import com.tasktop.c2c.server.common.web.client.notification.Message;
import com.tasktop.c2c.server.common.web.client.notification.OperationMessage;
import com.tasktop.c2c.server.common.web.client.presenter.AsyncCallbackSupport;
import com.tasktop.c2c.server.common.web.client.widgets.chooser.MultiValueChooser;
import com.tasktop.c2c.server.common.web.client.widgets.chooser.person.Person;
import com.tasktop.c2c.server.tasks.client.place.ProjectTasksPlace;
import com.tasktop.c2c.server.tasks.client.widgets.TaskSearchDisplay;
import com.tasktop.c2c.server.tasks.client.widgets.WidgetUtil;
import com.tasktop.c2c.server.tasks.client.widgets.presenter.person.KeywordSuggestService;
import com.tasktop.c2c.server.tasks.client.widgets.presenter.person.PersonUtil;
import com.tasktop.c2c.server.tasks.domain.FieldDescriptor;
import com.tasktop.c2c.server.tasks.domain.Keyword;
import com.tasktop.c2c.server.tasks.domain.RepositoryConfiguration;
import com.tasktop.c2c.server.tasks.domain.SavedTaskQuery;
import com.tasktop.c2c.server.tasks.domain.TaskFieldConstants;
import com.tasktop.c2c.server.tasks.domain.TaskUserProfile;
import com.tasktop.c2c.server.tasks.shared.action.UpdateQueryAction;
import com.tasktop.c2c.server.tasks.shared.action.UpdateQueryResult;

public class TaskSearchPresenter extends AbstractTaskPresenter {

    private String projectIdentifier;
    private final TaskSearchDisplay taskSearchView;
    protected RepositoryConfiguration repositoryConfiguration;
    private SavedTaskQuery editQuery;

    public TaskSearchPresenter(TaskSearchDisplay taskSearchView) {
        super(taskSearchView.getWidget());
        this.taskSearchView = taskSearchView;
        taskSearchView.setSearchClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                doSearch();
            }
        });
        taskSearchView.setSaveClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                doUpdateQuery();
            }
        });
    }

    @Override
    protected void bind() {
        //
    }

    void setState(String projectIdentifier, RepositoryConfiguration repositoryConfiguration) {
        this.projectIdentifier = projectIdentifier;
        this.repositoryConfiguration = repositoryConfiguration;
        configure();
    }

    private void configure() {
        taskSearchView.setRepositoryConfiguration(repositoryConfiguration);
        taskSearchView.setSelf(getAppState().getSelf());
        ProjectPersonService personService = new ProjectPersonService(projectIdentifier);
        taskSearchView.setPersonService(personService);
        taskSearchView.setKeywordService(new KeywordSuggestService(projectIdentifier));

        taskSearchView.createUi();

        maybeSetEditQueryToView();
    }

    private void addPeopleCriteria(NaryCriteria criteria, String fieldName, MultiValueChooser<Person> chooser) {
        NaryCriteria people = new NaryCriteria();
        people.setOperator(Operator.OR);

        // No persons chosen yet, just use the value in the text box if not empty.
        if (chooser.getValues().size() < 1 && !chooser.getSuggestBoxValue().isEmpty()) {
            people.addSubCriteria(
                    new ColumnCriteria(fieldName, Operator.EQUALS, querySafeValue(chooser.getSuggestBoxValue())));
        } else {
            for (Person person : chooser.getValues()) {
                people.addSubCriteria(new ColumnCriteria(fieldName, Operator.EQUALS, person.getIdentity()));
            }
        }
        if (people.hasSubCriteria()) {
            if (people.getSubCriteria().size() == 1) {
                criteria.addSubCriteria(people.getSubCriteria().get(0));
            } else {
                criteria.addSubCriteria(people);
            }
        }
    }

    private Criteria calculateCriteria() {
        NaryCriteria criteria = new NaryCriteria();
        criteria.setOperator(Operator.AND);

        Map<FieldDescriptor, Widget> descriptorToWidget = taskSearchView.getFieldDescriptorToWidget();
        @SuppressWarnings("unchecked")
        MultiValueChooser<Person> personChooser = (MultiValueChooser<Person>) descriptorToWidget
                .get(new FieldDescriptor("person"));

        @SuppressWarnings("unchecked")
        MultiValueChooser<Keyword> tagsChooser = (MultiValueChooser<Keyword>) descriptorToWidget
                .get(new FieldDescriptor("tags"));

        for (Entry<FieldDescriptor, Widget> entry : descriptorToWidget.entrySet()) {
            Widget widget = entry.getValue();
            if (widget instanceof MultiValueChooser<?>) {

                if (widget.equals(personChooser)) {
                    NaryCriteria peopleCriteria = new NaryCriteria();
                    peopleCriteria.setOperator(Operator.OR);

                    SimpleCheckBox creatorBox = (SimpleCheckBox) descriptorToWidget
                            .get(new FieldDescriptor(TaskFieldConstants.REPORTER_FIELD));
                    if (creatorBox.getValue()) {
                        addPeopleCriteria(peopleCriteria, TaskFieldConstants.REPORTER_FIELD, personChooser);
                    }

                    SimpleCheckBox ownerBox = ((SimpleCheckBox) descriptorToWidget
                            .get(new FieldDescriptor(TaskFieldConstants.ASSIGNEE_FIELD)));
                    if (ownerBox.getValue()) {
                        addPeopleCriteria(peopleCriteria, TaskFieldConstants.ASSIGNEE_FIELD, personChooser);
                    }

                    SimpleCheckBox commenterBox = (SimpleCheckBox) descriptorToWidget
                            .get(new FieldDescriptor(TaskFieldConstants.COMMENT_AUTHOR_FIELD));
                    if (commenterBox.getValue()) {
                        addPeopleCriteria(peopleCriteria, TaskFieldConstants.COMMENT_AUTHOR_FIELD, personChooser);
                    }

                    SimpleCheckBox watcherBox = (SimpleCheckBox) descriptorToWidget
                            .get(new FieldDescriptor(TaskFieldConstants.WATCHER_FIELD));
                    if (watcherBox.getValue()) {
                        addPeopleCriteria(peopleCriteria, TaskFieldConstants.WATCHER_FIELD, personChooser);
                    }

                    if (peopleCriteria.hasSubCriteria()) {
                        if (peopleCriteria.getSubCriteria().size() == 1) {
                            criteria.addSubCriteria(peopleCriteria.getSubCriteria().get(0));
                        } else {
                            criteria.addSubCriteria(peopleCriteria);
                        }
                    }
                } else if (widget.equals(tagsChooser)) {
                    NaryCriteria tagsCriteria = new NaryCriteria();
                    tagsCriteria.setOperator(Operator.OR);
                    for (Keyword k : tagsChooser.getValues()) {
                        tagsCriteria
                                .addSubCriteria(new ColumnCriteria(TaskFieldConstants.KEYWORDS_FIELD, k.getName()));
                    }
                    if (tagsCriteria.hasSubCriteria()) {
                        if (tagsCriteria.getSubCriteria().size() == 1) {
                            criteria.addSubCriteria(tagsCriteria.getSubCriteria().get(0));
                        } else {
                            criteria.addSubCriteria(tagsCriteria);
                        }
                    }
                } else {
                    // other choosers
                }

            } else if (widget instanceof ListBox) {
                // don't include dateType in the queryString
                if (widget.equals(descriptorToWidget.get(new FieldDescriptor("dateType")))) {
                    continue;
                }
                // all other ListBoxes
                ListBox listBox = (ListBox) widget;
                NaryCriteria values = new NaryCriteria();
                values.setOperator(Operator.OR);
                for (int index = 0; index < listBox.getItemCount(); ++index) {
                    if (listBox.isItemSelected(index)) {
                        String value = querySafeValue(listBox.getValue(index));
                        values.addSubCriteria(new ColumnCriteria(entry.getKey().getName(), Operator.EQUALS, value));
                    }
                }

                if (values.hasSubCriteria()) {
                    if (values.getSubCriteria().size() == 1) {
                        criteria.addSubCriteria(values.getSubCriteria().get(0));
                    } else {
                        criteria.addSubCriteria(values);
                    }
                }

            } else if (widget instanceof TextBox) {
                TextBox summaryDescriptionCommentsTextBox = (TextBox) descriptorToWidget
                        .get(new FieldDescriptor("summaryDescriptionComments"));

                if (widget.equals(summaryDescriptionCommentsTextBox)) {
                    String value = summaryDescriptionCommentsTextBox.getValue();
                    if (value != null && value.trim().length() > 0) {
                        value = value.trim();
                        NaryCriteria summaryDescSearch = new NaryCriteria();
                        summaryDescSearch.setOperator(Operator.OR);
                        SimpleCheckBox summaryBox = (SimpleCheckBox) descriptorToWidget
                                .get(new FieldDescriptor(TaskFieldConstants.SUMMARY_FIELD));
                        SimpleCheckBox descriptionBox = (SimpleCheckBox) descriptorToWidget
                                .get(new FieldDescriptor(TaskFieldConstants.DESCRIPTION_FIELD));
                        if (summaryBox.getValue()) {
                            summaryDescSearch.addSubCriteria(new ColumnCriteria(TaskFieldConstants.SUMMARY_FIELD,
                                    Operator.STRING_CONTAINS, value));
                        }
                        if (descriptionBox.getValue()) {
                            summaryDescSearch.addSubCriteria(new ColumnCriteria(
                                    TaskFieldConstants.DESCRIPTION_FIELD, Operator.STRING_CONTAINS, value));
                            summaryDescSearch.addSubCriteria(new ColumnCriteria(TaskFieldConstants.COMMENT_FIELD,
                                    Operator.STRING_CONTAINS, value));
                        }
                        if (summaryDescSearch.hasSubCriteria()) {
                            if (summaryDescSearch.getSubCriteria().size() == 1) {
                                criteria.addSubCriteria(summaryDescSearch.getSubCriteria().get(0));
                            } else {
                                criteria.addSubCriteria(summaryDescSearch);
                            }
                        }
                    }
                }
                // All other text boxes
                else {
                    TextBox text = (TextBox) widget;
                    String value = querySafeValue(text.getText());
                    if (value != null && value.trim().length() > 0) {
                        value = value.trim();
                        criteria.addSubCriteria(
                                new ColumnCriteria(entry.getKey().getName(), Operator.STRING_CONTAINS, value));
                    }
                }

            } else if (widget instanceof DateBox) {
                ListBox dateTypeListBox = (ListBox) descriptorToWidget.get(new FieldDescriptor("dateType"));
                String selectedDateType = dateTypeListBox.getValue(dateTypeListBox.getSelectedIndex());
                String dateTypeField = null;
                if (selectedDateType.equals("Created")) {
                    dateTypeField = TaskFieldConstants.CREATION_TIME_FIELD;
                } else if (selectedDateType.equals("Updated")) {
                    dateTypeField = TaskFieldConstants.LAST_UPDATE_FIELD;
                }
                if (dateTypeField != null) {
                    DateBox startDateBox = (DateBox) descriptorToWidget.get(new FieldDescriptor("startDate"));
                    DateBox endDateBox = (DateBox) descriptorToWidget.get(new FieldDescriptor("endDate"));
                    if (widget.equals(startDateBox)) {
                        if (startDateBox.getValue() != null) {
                            Date value = startDateBox.getValue();
                            criteria.addSubCriteria(
                                    new ColumnCriteria(dateTypeField, Operator.GREATER_THAN, value));
                        }
                    } else if (widget.equals(endDateBox)) {
                        if (endDateBox.getValue() != null) {
                            Date value = endDateBox.getValue();
                            criteria.addSubCriteria(new ColumnCriteria(dateTypeField, Operator.LESS_THAN, value));
                        }
                    }
                }
            }
        }
        return criteria;
    }

    private void maybeSetEditQueryToView() {
        clearWidgets(editQuery == null);
        if (editQuery != null) {
            updateWidgetsWithCriteria(editQuery.getQueryCriteria());
        }
    }

    private void clearWidgets(boolean checkBoxValue) {
        for (Widget w : taskSearchView.getFieldDescriptorToWidget().values()) {
            if (w instanceof SimpleCheckBox) {
                ((SimpleCheckBox) w).setValue(checkBoxValue);
            } else if (w instanceof TakesValue<?>) {
                ((TakesValue<?>) w).setValue(null);
            } else if (w instanceof ListBox) {
                for (int i = 0; i < ((ListBox) w).getItemCount(); i++) {
                    ((ListBox) w).setItemSelected(i, false);
                }
            } else if (w instanceof MultiValueChooser) {
                ((MultiValueChooser<?>) w).setValues(Collections.EMPTY_LIST);
            }
        }
    }

    protected void doSearch() {
        ProjectTasksPlace.createPlaceForCriteriaQuery(projectIdentifier, calculateCriteria().toString()).go();
    }

    private void updateWidgetsWithCriteria(Criteria crit) {
        if (crit instanceof ColumnCriteria) {
            ColumnCriteria columnCriteria = (ColumnCriteria) crit;
            String field = columnCriteria.getColumnName();

            // Date
            if (field.equals(TaskFieldConstants.LAST_UPDATE_FIELD)
                    || field.equals(TaskFieldConstants.CREATION_TIME_FIELD)) {
                ListBox dateTypeListBox = (ListBox) getWidgetForField("dateType");
                String listBoxValue = field.equals(TaskFieldConstants.LAST_UPDATE_FIELD) ? "Updated" : "Created";
                WidgetUtil.select(dateTypeListBox, listBoxValue);
                switch (columnCriteria.getOperator()) {
                case GREATER_THAN:
                    DateBox startDateBox = (DateBox) getWidgetForField("startDate");
                    startDateBox.setValue((Date) columnCriteria.getColumnValue());
                    break;
                case LESS_THAN:
                    DateBox endDateBox = (DateBox) getWidgetForField("endDate");
                    endDateBox.setValue((Date) columnCriteria.getColumnValue());
                    break;
                default:
                    throw new UnsupportedOperationException("Can not parse date crit");

                }
                return;
            }
            // Keywords
            else if (field.endsWith(TaskFieldConstants.KEYWORDS_FIELD)) {
                MultiValueChooser<Keyword> keywordChooser = (MultiValueChooser<Keyword>) getWidgetForField("tags");
                Keyword keyword = null;
                for (Keyword k : repositoryConfiguration.getKeywords()) {
                    if (k.getName().equals(columnCriteria.getColumnValue())) {
                        keyword = k;
                        break;
                    }
                }
                keywordChooser.addValue(keyword, false);
                return;
            }
            // People
            else if (field.equals(TaskFieldConstants.REPORTER_FIELD)
                    || field.equals(TaskFieldConstants.ASSIGNEE_FIELD)
                    || field.equals(TaskFieldConstants.COMMENT_AUTHOR_FIELD)
                    || field.equals(TaskFieldConstants.WATCHER_FIELD)) {
                TakesValue<Boolean> box = (TakesValue<Boolean>) getWidgetForField(field);
                box.setValue(true);

                MultiValueChooser<Person> personChooser = (MultiValueChooser<Person>) getWidgetForField("person");
                String personLogin = columnCriteria.getColumnValue().toString();
                Person person = new Person(personLogin, personLogin);
                for (TaskUserProfile taskPerson : repositoryConfiguration.getUsers()) {
                    if (taskPerson.getLoginName().equals(personLogin)) {
                        person = PersonUtil.toPerson(taskPerson);
                        break;
                    }
                }
                personChooser.addValue(person, false);
                return;
            }
            // Text
            else if (field.equals(TaskFieldConstants.SUMMARY_FIELD)
                    || field.equals(TaskFieldConstants.DESCRIPTION_FIELD)) {
                TakesValue<Boolean> box = (TakesValue<Boolean>) getWidgetForField(field);
                box.setValue(true);

                TextBox textBox = (TextBox) getWidgetForField("summaryDescriptionComments");
                textBox.setValue(columnCriteria.getColumnValue().toString());
                return;
            } else if (field.equals(TaskFieldConstants.COMMENT_FIELD)) {
                // Ignore this because it is part of the above
                return;
            }

            // Generic
            Widget value = getWidgetForField(field);
            if (value == null) {
                throw new UnsupportedOperationException("Can not parse, unknown field: " + field);
            }
            if (value instanceof TextBox) {
                ((TextBox) value).setText(columnCriteria.getColumnValue().toString());
            } else if (value instanceof ListBox) {
                ListBox listBox = (ListBox) value;
                String colValue = columnCriteria.getColumnValue().toString();
                for (int i = 0; i < listBox.getItemCount(); i++) {
                    if (listBox.getItemText(i).equals(colValue)) {
                        listBox.setItemSelected(i, true);
                        return;
                    }
                }
            }
        } else if (crit instanceof NaryCriteria) {
            // FIXME/REVIEW this is not necessarly correct, not all crit can be represented in this UI
            NaryCriteria naryCriteria = (NaryCriteria) crit;
            for (Criteria sub : naryCriteria.getSubCriteria()) {
                updateWidgetsWithCriteria(sub);
            }
        }
    }

    private Widget getWidgetForField(String fieldName) {
        for (Entry<FieldDescriptor, Widget> e : taskSearchView.getFieldDescriptorToWidget().entrySet()) {
            if (e.getKey().getName().equals(fieldName)) {
                return e.getValue();
            }
        }
        return null;
    }

    private String querySafeValue(String text) {
        if (text == null) {
            return null;
        }
        // can't have '?' in our query string, see bug 1649
        return text.replace("?", "");
    }

    public void setEditQuery(SavedTaskQuery editQuery) {
        this.editQuery = editQuery;
        this.taskSearchView.setEditQuery(editQuery);

        if (this.repositoryConfiguration != null) {
            maybeSetEditQueryToView();
        } // Otherwise this happens after the view is configured
    }

    public void setEditCriteria(Criteria criteria) {
        this.editQuery = null;
        this.taskSearchView.setEditQuery(null);
        updateWidgetsWithCriteria(criteria);
    }

    // REVIEW consider pushing this up to TasksPresenter. Then we can just swap out some displays and avoid full reload
    private void doUpdateQuery() {
        editQuery.setQueryString(calculateCriteria().toQueryString());
        getDispatchService().execute(new UpdateQueryAction(projectIdentifier, editQuery),
                new AsyncCallbackSupport<UpdateQueryResult>(
                        new OperationMessage(super.commonProfileMessages.saving())) {

                    @Override
                    protected void success(UpdateQueryResult actionResult) {
                        ProjectTasksPlace place = ProjectTasksPlace.createPlaceForNamedQuery(projectIdentifier,
                                editQuery.getName());
                        place.displayOnArrival(Message.createSuccessMessage(tasksMessages.querySaved()));
                        place.go();
                    }
                });
    }

}