org.hip.vif.admin.groupadmin.ui.BibliographySearchView.java Source code

Java tutorial

Introduction

Here is the source code for org.hip.vif.admin.groupadmin.ui.BibliographySearchView.java

Source

/**
   This package is part of the application VIF.
   Copyright (C) 2011-2014, Benno Luthiger
    
   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; either version 2 of the License, or
   (at your option) any later version.
    
   This program 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, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package org.hip.vif.admin.groupadmin.ui;

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

import org.hip.vif.admin.groupadmin.Activator;
import org.hip.vif.admin.groupadmin.data.ContributionContainer;
import org.hip.vif.admin.groupadmin.data.ContributionWrapper;
import org.hip.vif.admin.groupadmin.tasks.BibliographyHandleTask;
import org.hip.vif.core.bom.Group;
import org.hip.vif.core.bom.Question;
import org.hip.vif.core.bom.QuestionHome;
import org.hip.vif.web.util.AutoCompleteHelper;
import org.hip.vif.web.util.BeanWrapperHelper;
import org.hip.vif.web.util.VIFViewHelper;
import org.ripla.interfaces.IMessages;
import org.ripla.web.util.LabelValueTable;
import org.ripla.web.util.RiplaViewHelper;

import com.vaadin.data.Container;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.shared.ui.combobox.FilteringMode;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.Notification.Type;
import com.vaadin.ui.Table;
import com.vaadin.ui.VerticalLayout;

/** The form to search for Bibliography entries to be linked to a question.
 *
 * @author Luthiger Created: 01.09.2011 */
@SuppressWarnings("serial")
public class BibliographySearchView extends AbstractContributionView {

    private final ComboBox title;
    private final ComboBox author;

    /** View constructor.
     *
     * @param inQuestion {@link Question} the actual question, possibly the question the bibliography will be linked
     *            with
     * @param inGroup {@link Group} the actual group
     * @param inTitles {@link IndexedContainer} the titles of existing bibliography entries, to be filled in the combo
     *            box
     * @param inAuthors {@link IndexedContainer} the authors of existing bibliography entries, to be filled in the combo
     *            box
     * @param inTask {@link BibliographyHandleTask} the task (controller) of this view */
    public BibliographySearchView(final Question inQuestion, final Group inGroup, final IndexedContainer inTitles,
            final IndexedContainer inAuthors, final BibliographyHandleTask inTask) {
        final VerticalLayout lLayout = new VerticalLayout();
        setCompositionRoot(lLayout);
        lLayout.setSpacing(true);

        final IMessages lMessages = Activator.getMessages();
        lLayout.setStyleName("vif-view"); //$NON-NLS-1$
        final String lTitle = lMessages.getFormattedMessage("ui.bibliography.link.title.page", //$NON-NLS-1$
                BeanWrapperHelper.getPlain(QuestionHome.KEY_QUESTION, inQuestion),
                BeanWrapperHelper.getString(QuestionHome.KEY_QUESTION_DECIMAL, inQuestion));
        lLayout.addComponent(
                new Label(String.format(VIFViewHelper.TMPL_TITLE, "vif-pagetitle", lTitle), ContentMode.HTML)); //$NON-NLS-1$

        lLayout.addComponent(new Label(lMessages.getMessage("ui.bibliography.link.remark"), ContentMode.HTML)); //$NON-NLS-1$

        final LabelValueTable lTable = new org.ripla.web.util.LabelValueTable();
        title = createComboBox(inTitles);
        title.focus();
        lTable.addRow(lMessages.getMessage("ui.bibliography.label.title"), title); //$NON-NLS-1$

        author = createComboBox(inAuthors);
        lTable.addRow(lMessages.getMessage("ui.bibliography.label.author"), author); //$NON-NLS-1$
        lLayout.addComponent(lTable);

        final Button lSearch = new Button(lMessages.getMessage("ui.bibliography.link.button.search")); //$NON-NLS-1$
        final Button lCreate = new Button(lMessages.getMessage("ui.bibliography.link.button.create")); //$NON-NLS-1$
        lCreate.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(final ClickEvent inEvent) {
                if (!inTask.createNew(title.getValue(), author.getValue())) {
                    Notification.show(Activator.getMessages().getMessage("errmsg.save.general"), //$NON-NLS-1$
                            Type.WARNING_MESSAGE);
                }
            }
        });
        lCreate.setVisible(false);

        final ResultView lResultView = new ResultView(inTask);
        lResultView.setVisible(false);

        lSearch.setClickShortcut(KeyCode.ENTER);
        lSearch.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(final ClickEvent inEvent) {
                if (inTask.searchFor(title.getValue(), author.getValue())) {
                    lCreate.setVisible(true);
                    lResultView.fillTable(inTask.getTexts());
                    lResultView.setVisible(true);
                }
            }
        });

        lLayout.addComponent(RiplaViewHelper.createButtons(lSearch, lCreate));
        lLayout.addComponent(RiplaViewHelper.createSpacer());
        lLayout.addComponent(lResultView);
    }

    private ComboBox createComboBox(final IndexedContainer inEntries) {
        final ComboBox out = new AutoCompleteSelection();
        out.setContainerDataSource(inEntries);
        out.setItemCaptionMode(ItemCaptionMode.ID);
        out.setWidth(400, Unit.PIXELS);
        out.setFilteringMode(FilteringMode.STARTSWITH);
        out.setImmediate(true);
        out.setStyleName("vif-input"); //$NON-NLS-1$
        return out;
    }

    // ---

    /** Extended <code>ComboBox</code> to attach lazy loading behavior.
     *
     * @author Luthiger Created: 11.09.2011 */
    private static class AutoCompleteSelection extends ComboBox {
        private String filterString;
        private boolean filteringContainer;

        @Override
        public void containerItemSetChange(final Container.ItemSetChangeEvent inEvent) {
            if (!filteringContainer) {
                super.containerItemSetChange(inEvent);
            }
        }

        @Override
        public void changeVariables(final Object inSource, final Map<String, Object> inVariables) {
            filterString = (String) inVariables.get("filter"); //$NON-NLS-1$
            if (filterString != null) {
                filterString = filterString.toLowerCase();
            }
            super.changeVariables(inSource, inVariables);
        }

        /** Lazy loading happens here: We call the container's lazy loading methods. */
        @Override
        protected List<?> getFilteredOptions() {
            final Container lContainer = getContainerDataSource();
            if (!(lContainer instanceof AutoCompleteHelper.LazyLoadingBibliographyContainer)) {
                return super.getFilteredOptions();
            }

            final Filterable lFilterable = (Filterable) lContainer;
            final Filter lFilter = buildFilter(filterString, getFilteringMode());
            if (lFilter == null) {
                return Collections.EMPTY_LIST;
            }

            filteringContainer = true;
            lFilterable.addContainerFilter(lFilter);
            final Indexed lIndexed = (Indexed) lContainer;
            final int lFilteredSize = lContainer.size();
            final List<Object> lOptions = new ArrayList<Object>();
            for (int i = 0; i < lFilteredSize; ++i) {
                lOptions.add(lIndexed.getIdByIndex(i));
            }

            // to the outside, filtering should not be visible
            if (lFilter != null) {
                lFilterable.removeContainerFilter(lFilter);
            }
            filteringContainer = false;

            return lOptions;
        }
    }

    /** View component to display the table of search results.
     *
     * @author Luthiger Created: 25.09.2011 */
    private static class ResultView extends CustomComponent {
        private static final String[] COL_HEADERS = new String[] { "", "container.table.headers.id", //$NON-NLS-1$//$NON-NLS-2$
                "container.table.headers.text" }; //$NON-NLS-1$

        private Component table;
        private final VerticalLayout layout;
        private ContributionContainer texts;
        private final BibliographyHandleTask bibliographyTask;

        /** Constructor
         *
         * @param inTask BibliographyHandleTask */
        ResultView(final BibliographyHandleTask inTask) {
            bibliographyTask = inTask;
            layout = new VerticalLayout();
            setCompositionRoot(layout);
            layout.setSpacing(true);

            final IMessages lMessages = Activator.getMessages();
            layout.addComponent(new Label(String.format(VIFViewHelper.TMPL_TITLE, "vif-subtitle", //$NON-NLS-1$
                    lMessages.getMessage("ui.bibliography.link.subtitle")), ContentMode.HTML)); //$NON-NLS-1$

            table = new Label("Dummy"); //$NON-NLS-1$
            layout.addComponent(table);

            final Button lAdd = new Button(lMessages.getMessage("ui.bibliography.link.button.link")); //$NON-NLS-1$
            final Button lEdit = new Button(lMessages.getMessage("ui.bibliography.link.button.edit")); //$NON-NLS-1$
            final Button lDelete = new Button(lMessages.getMessage("ui.bibliography.link.button.delete")); //$NON-NLS-1$
            layout.addComponent(RiplaViewHelper.createButtons(lAdd, lEdit, lDelete));

            lAdd.addClickListener(new ClickListener() {
                @Override
                public void buttonClick(final ClickEvent inEvent) {
                    if (VIFViewHelper.processAction(texts)) {
                        bibliographyTask.addBibliography();
                    }
                }
            });

            lEdit.addClickListener(new ClickListener() {
                @Override
                public void buttonClick(final ClickEvent inEvent) {
                    if (VIFViewHelper.processAction(texts)) {
                        inTask.editBibliography();
                    }
                }
            });

            lDelete.addClickListener(new ClickListener() {
                @Override
                public void buttonClick(final ClickEvent inEvent) {
                    if (VIFViewHelper.processAction(texts)) {
                        if (!bibliographyTask.deleteBibliography()) {
                            Notification.show(lMessages.getMessage("errmsg.contribution.delete"), //$NON-NLS-1$
                                    Type.WARNING_MESSAGE);
                        }
                    }
                }
            });
        }

        /** Fill the table according to the information entered into the combo boxes.
         *
         * @param inTexts ContributionContainer */
        void fillTable(final ContributionContainer inTexts) {
            if (inTexts == null)
                return;
            if (!inTexts.hasItems())
                return;

            texts = inTexts;
            final Component lOld = table;

            table = createTable(inTexts);
            layout.replaceComponent(lOld, table);
        }

        Component createTable(final ContributionContainer inTexts) {
            final Table outTable = new Table();

            outTable.setStyleName("vif-table"); //$NON-NLS-1$
            outTable.setWidth("100%"); //$NON-NLS-1$

            outTable.setContainerDataSource(inTexts);
            // generate check box
            outTable.addGeneratedColumn(ContributionContainer.CONTRIBUTION_CHECK,
                    new VIFViewHelper.CheckBoxColumnGenerator(new VIFViewHelper.IConfirmationModeChecker() {
                        @Override
                        public boolean inConfirmationMode() {
                            return false;
                        }
                    }));
            // generate label component for html text
            outTable.addGeneratedColumn(ContributionContainer.CONTRIBUTION_TEXT, new Table.ColumnGenerator() {
                @Override
                public Component generateCell(final Table inSource, final Object inItemId,
                        final Object inColumnId) {
                    return new Label(((ContributionWrapper) inItemId).getContributionText(), ContentMode.HTML);
                }
            });

            outTable.setColumnCollapsingAllowed(true);
            outTable.setColumnReorderingAllowed(true);
            outTable.setSelectable(true);
            outTable.setImmediate(true);
            outTable.setPageLength(0);
            outTable.setColumnExpandRatio(ContributionContainer.CONTRIBUTION_TEXT, 1);
            outTable.addValueChangeListener(bibliographyTask);

            outTable.setVisibleColumns(ContributionContainer.NATURAL_COL_ORDER_WO_STATE);
            outTable.setColumnHeaders(VIFViewHelper.getColumnHeaders(COL_HEADERS, Activator.getMessages()));

            return outTable;
        }
    }

}