com.userweave.pages.configuration.study.localization.StudyLocalizationPanel.java Source code

Java tutorial

Introduction

Here is the source code for com.userweave.pages.configuration.study.localization.StudyLocalizationPanel.java

Source

/*******************************************************************************
 * This file is part of UserWeave.
 *
 *     UserWeave is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     UserWeave 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 Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with UserWeave.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Copyright 2012 User Prompt GmbH | Psychologic IT Expertise
 *******************************************************************************/
package com.userweave.pages.configuration.study.localization;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Page;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;

import com.userweave.components.IToolTipComponent.ToolTipType;
import com.userweave.components.authorization.AuthOnlyAjaxLink;
import com.userweave.components.authorization.AuthOnlyDropDownChoice;
import com.userweave.components.authorization.IAuthOnly;
import com.userweave.components.callback.EventHandler;
import com.userweave.components.customModalWindow.CustomModalWindow;
import com.userweave.components.model.LocaleModel;
import com.userweave.dao.StudyDao;
import com.userweave.domain.Study;
import com.userweave.domain.StudyState;
import com.userweave.pages.configuration.DisableFormComponentVisitor;
import com.userweave.pages.configuration.DisableLinkVisitor;
import com.userweave.pages.configuration.EnabledInStudyState;
import com.userweave.presentation.model.EntityBaseLoadableDetachableModel;

/**
 * Panel to add and configure locales.
 * 
 * @author oma
 * @author opr
 */
public class StudyLocalizationPanel extends Panel {
    private static final long serialVersionUID = 1L;

    /**
     * Authorized version of a bookmarkable page link. 
     * Is only enabled,if a user is authorized, that 
     * is, if he is admin or participant.
     * 
     * @author opr
     */
    private class AuthOnlyBookmarkablePageLink extends BookmarkablePageLink<Void> implements IAuthOnly {
        private static final long serialVersionUID = 1L;

        /**
         * Flag to indicate if a user can use this link.
         */
        private boolean isAuthorized = false;

        /**
         * {@inheritDoc}
         */
        public AuthOnlyBookmarkablePageLink(String id, Class<TranslationPage> pageClass,
                PageParameters parameters) {
            super(id, pageClass, parameters);
        }

        @Override
        public void setIsAuthorized(boolean isAuthorized) {
            this.isAuthorized = isAuthorized;
        }

        @Override
        public boolean isEnabled() {
            return super.isEnabled() && isAuthorized && getStudy().getState() == StudyState.INIT; // @see #1310
        }

        @Override
        protected void onBeforeRender() {
            if (!isEnabled()) {
                add(new AttributeModifier("title", new StringResourceModel(ToolTipType.PHASE.getStringResourceKey(),
                        new AuthOnlyAjaxLink("dummy") {
                            private static final long serialVersionUID = 1L;

                            @Override
                            public void onClick(AjaxRequestTarget target) {
                            }
                        }, null)));
            }
            super.onBeforeRender();
        }

    }

    /**
     * Auth link which is only visible, when the study is in 
     * init state.
     * 
     * @author opr
     */
    @EnabledInStudyState(states = { StudyState.INIT })
    private abstract class StudyStateDependAjaxLink extends AuthOnlyAjaxLink {
        private static final long serialVersionUID = 1L;

        /**
         * {@inheritDoc}
         */
        public StudyStateDependAjaxLink(String id) {
            super(id);

            setToolTipType(ToolTipType.PHASE);
        }
    }

    /**
     * Auth drop down, which is enabeled, when the 
     * study is in running or init state.
     * 
     * @author opr
     */
    @EnabledInStudyState(states = { StudyState.INIT })
    private class StudyStateDependDropDownChoice extends AuthOnlyDropDownChoice {
        private static final long serialVersionUID = 1L;

        public StudyStateDependDropDownChoice(String id, IModel<Boolean> model, List<Boolean> data,
                IChoiceRenderer<Boolean> renderer) {
            super(id, model, data, renderer);
        }
    }

    @SpringBean
    private StudyDao studyDao;

    /**
     * Container for a list of configurable locales.
     */
    private WebMarkupContainer localesContainer;

    /**
     * Model value for the drop down.
     */
    private boolean isLocaleSelectable;

    private Form<Void> form;

    /**
     * Default constructor.
     * 
     * @param id
     *       Component markup id
     * @param studyId
     *       Id of underlying study.
     * @param callback
     *       Callback to fire on event.
     */
    public StudyLocalizationPanel(String id, final int studyId, final EventHandler callback) {
        super(id, new EntityBaseLoadableDetachableModel<Study>(Study.class, studyId));

        // only display the default locale.
        add(new Label("default_locale", ((Study) getDefaultModelObject()).getLocale().getDisplayLanguage()));

        localesContainer = getListView();

        add(localesContainer);

        final CustomModalWindow addLocaleModal = getAddLocaleModal();

        add(addLocaleModal);

        add(new StudyStateDependAjaxLink("addLocale") {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClick(AjaxRequestTarget target) {
                addLocaleModal.show(target);
            }
        });

        addSelectableLocalePanelDropDown();
    }

    @Override
    protected void onBeforeRender() {
        IModel<StudyState> stateModel = new PropertyModel<StudyState>(getDefaultModel(), "state");

        // disable link when study not in init-state
        visitChildren(new DisableLinkVisitor(stateModel));

        // disable form components, when study not in init-state
        form.visitFormComponents(new DisableFormComponentVisitor<FormComponent<?>>(stateModel));

        super.onBeforeRender();
    }

    /**
     * Factory method to create a new list view, which displays 
     * all configurable locales.
     * 
     * @return
     *       A web markup container, wrapping a list view.
     */
    private WebMarkupContainer getListView() {
        IModel<List<Locale>> localeChoiceModel = new LoadableDetachableModel<List<Locale>>() {
            private static final long serialVersionUID = 1L;

            @Override
            protected List<Locale> load() {
                return getStudy().getSupportedLocalesWithoutMainLocale();
            }

        };

        // each list view item has a label for the locale name,
        // a link to his translation page an a delete button.
        ListView<Locale> lv = new ListView<Locale>("localeList", localeChoiceModel) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(final ListItem<Locale> item) {
                item.add(new Label("locale", new LocaleModel(item.getModel(), getLocale())));

                PageParameters parameters = new PageParameters();

                parameters.set(1, item.getModelObject().toString());
                parameters.set(0, getStudy().getHashCode());

                item.add(new AuthOnlyBookmarkablePageLink("open", TranslationPage.class, parameters));

                item.add(createDeleteLink(item));
            }
        };

        WebMarkupContainer container = new WebMarkupContainer("localesContainer");
        container.add(lv);
        container.setOutputMarkupId(true);

        return container;
    }

    /**
     * @param item
     * @return
     */
    private AuthOnlyAjaxLink createDeleteLink(final ListItem<Locale> item) {
        return new AuthOnlyAjaxLink("delete", ToolTipType.PHASE) {
            private static final long serialVersionUID = 1L;

            @Override
            public boolean isEnabled() {
                return super.isEnabled() && getStudy().getState() == StudyState.INIT;
            }

            @Override
            public void onClick(AjaxRequestTarget target) {
                Study study = getStudy();

                study.getSupportedLocales().remove(item.getModelObject());

                studyDao.save(study);

                replaceListView(target);
            }
        };
    }

    /**
     * Convenient method to replace the list of locales.
     * 
     * @param target
     *       Ajax request target.
     */
    private void replaceListView(AjaxRequestTarget target) {
        WebMarkupContainer replacement = getListView();

        localesContainer.replaceWith(replacement);

        localesContainer = replacement;

        target.add(localesContainer);
    }

    /**
     * Factory method to create the dialog to add a new locale.
     * 
     * @return
     *       A Custom modal winodow.
     */
    private CustomModalWindow getAddLocaleModal() {
        final CustomModalWindow window = new CustomModalWindow("addLocaleModal");

        window.setTitle(new StringResourceModel("addLocale", this, null));

        window.setPageCreator(new ModalWindow.PageCreator() {
            private static final long serialVersionUID = 1L;

            @Override
            public Page createPage() {
                return new AddLocalePage(window, getDefaultModel()) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    protected IModel<String> getAcceptLabel() {
                        return window.getTitle();
                    }

                    @Override
                    protected void onAddLocale(AjaxRequestTarget target, List<Locale> locales) {
                        Study study = getStudy();
                        study.getSupportedLocales().addAll(locales);
                        studyDao.save(study);
                    }
                };
            }
        });

        window.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
            private static final long serialVersionUID = 1L;

            @Override
            public void onClose(AjaxRequestTarget target) {
                replaceListView(target);
            }
        });

        return window;
    }

    /**
     * Creates and add a drop down to decide, if the locale panel
     * at the beginning of a study is visible or if the browser 
     * locale should be used.
     */
    private void addSelectableLocalePanelDropDown() {
        form = new Form<Void>("form");

        add(form);

        isLocaleSelectable = getStudy().isLocaleSelectable();

        StudyStateDependDropDownChoice choice = new StudyStateDependDropDownChoice("locale_selectable",
                new PropertyModel<Boolean>(StudyLocalizationPanel.this, "isLocaleSelectable"),
                Arrays.asList(new Boolean[] { true, false }), new IChoiceRenderer<Boolean>() {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public String getIdValue(Boolean object, int index) {
                        return object.toString() + index;
                    }

                    @Override
                    public Object getDisplayValue(Boolean object) {
                        if (object) {
                            return new StringResourceModel("manualSelection", StudyLocalizationPanel.this, null)
                                    .getObject();
                        }

                        return new StringResourceModel("automaticSelection", StudyLocalizationPanel.this, null)
                                .getObject();
                    }
                });

        choice.add(new AjaxFormComponentUpdatingBehavior("onchange") {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                getStudy().setLocaleSelectable(isLocaleSelectable);
                studyDao.save(getStudy());
            }
        });

        form.add(choice);
    }

    /**
     * Shortcut to the study object.
     * 
     * @return
     *       The underlying study.
     */
    private Study getStudy() {
        return (Study) getDefaultModelObject();
    }
}