001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.apps.git;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsUser;
032import org.opencms.main.CmsException;
033import org.opencms.main.CmsLog;
034import org.opencms.main.OpenCms;
035import org.opencms.module.CmsModule;
036import org.opencms.ui.A_CmsUI;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.components.CmsResourceInfo;
039import org.opencms.util.CmsStringUtil;
040import org.opencms.workplace.CmsWorkplace;
041
042import java.util.ArrayList;
043import java.util.Collection;
044import java.util.Collections;
045import java.util.List;
046import java.util.Map;
047
048import org.apache.commons.logging.Log;
049
050import com.google.common.base.Strings;
051import com.google.common.collect.Lists;
052import com.google.common.collect.Maps;
053import com.vaadin.ui.AbstractLayout;
054import com.vaadin.ui.Alignment;
055import com.vaadin.ui.Button;
056import com.vaadin.ui.Button.ClickEvent;
057import com.vaadin.ui.Button.ClickListener;
058import com.vaadin.ui.Component;
059import com.vaadin.ui.Notification;
060import com.vaadin.ui.Notification.Type;
061import com.vaadin.ui.Panel;
062import com.vaadin.ui.TabSheet;
063import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
064import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
065import com.vaadin.ui.Window;
066import com.vaadin.ui.themes.ValoTheme;
067import com.vaadin.v7.data.Property.ValueChangeEvent;
068import com.vaadin.v7.data.Property.ValueChangeListener;
069import com.vaadin.v7.shared.ui.combobox.FilteringMode;
070import com.vaadin.v7.shared.ui.label.ContentMode;
071import com.vaadin.v7.ui.CheckBox;
072import com.vaadin.v7.ui.ComboBox;
073import com.vaadin.v7.ui.HorizontalLayout;
074import com.vaadin.v7.ui.Label;
075import com.vaadin.v7.ui.TextArea;
076import com.vaadin.v7.ui.TextField;
077import com.vaadin.v7.ui.VerticalLayout;
078
079/**
080 * Main widget for the Git check-in tool.<p>
081 */
082public class CmsGitToolOptionsPanel extends VerticalLayout {
083
084    /**
085     * Enum describing the type of action to perform.<p>
086     */
087    enum ActionType {
088        /** Check in. */
089        checkIn,
090
091        /** Checkout action. */
092        checkOut,
093
094        /** Reset to HEAD. */
095        resetHead,
096
097        /** Reset to remote head. */
098        resetRemoteHead;
099    }
100
101    /**
102     * Enum representing the dialog's tabs.
103     */
104    enum DialogTab {
105        /** The 'check in' tab. */
106        checkIn,
107
108        /** The 'import' tab. */
109        checkOut;
110    }
111
112    /** Additional info key for the email address. */
113    public static final String ADDINFO_EMAIL = "git_cms_email";
114
115    /** Additional info key for the commit message. */
116    public static final String ADDINFO_MESSAGE = "git_cms_message";
117
118    /** Additional info key for the user name. */
119    public static final String ADDINFO_USER = "git_cms_user";
120
121    /** Logger instance for this class. */
122    private static final Log LOG = CmsLog.getLog(CmsGitToolOptionsPanel.class);
123
124    /** Serial version id. */
125    private static final long serialVersionUID = 1L;
126
127    /** True when advanced options are currently visible. */
128    protected boolean m_advancedVisible;
129
130    /** Map of check boxes for selectable modules, with the module names as keys. */
131    Map<String, CheckBox> m_moduleCheckboxes = Maps.newHashMap();
132
133    /** Field for 'Add and commit' setting. */
134    private CheckBox m_addAndCommit;
135
136    /** The advanced options layout. */
137    private VerticalLayout m_advancedLayout;
138
139    /** Cancel button. */
140    private Button m_cancel;
141
142    /** The check-in bean. */
143    private CmsGitCheckin m_checkinBean;
144
145    /** The tab with the import settings. */
146    private Component m_checkoutTab;
147
148    /** Field for 'Commit message' setting. */
149    private TextArea m_commitMessage;
150
151    /** Panel for the configuration selection. */
152    private Panel m_configurationSelectionPanel;
153
154    /** Configuration selector. */
155    private ComboBox m_configurationSelector;
156
157    /** Field for 'Copy and unzip' setting. */
158    private CheckBox m_copyAndUnzip;
159
160    /** Current window (using an array so the Vaadin field binder doesn't process this. */
161    private Window[] m_currentWindow = new Window[] {null};
162
163    /** Button for deselecting all modules. */
164    private Button m_deselectAll;
165
166    /** The initial dialog tab. */
167    private DialogTab m_dialogTab = DialogTab.checkIn;
168
169    /** The field for the email address. */
170    private TextField m_emailField;
171
172    /** Field for 'Exclude lib' setting. */
173    private CheckBox m_excludeLib;
174
175    /** Email field for module import. */
176    private TextField m_fakeEmailField;
177
178    /** User field for module import. */
179    private TextField m_fakeUserField;
180
181    /** Checkbox for the 'fetch and reset' option. */
182    private CheckBox m_fetchAndReset;
183
184    /** Field for 'Ignroe unclean' setting. */
185    private CheckBox m_ignoreUnclean;
186
187    /** Selected mode. */
188    private ActionType m_mode = ActionType.checkIn;
189
190    /** Container for the module selector. */
191    private VerticalLayout m_moduleSelectionContainer;
192
193    /** Module selector. */
194    private ComboBox m_moduleSelector;
195
196    /** Container for the module selector drop-down and the "Deselect all" button. */
197    private HorizontalLayout m_moduleSelectorContainer;
198
199    /** Button for check-in. */
200    private Button m_okButton;
201
202    /** Field for 'Pull after commit' setting. */
203    private CheckBox m_pullAfterCommit;
204
205    /** Field for 'Pull first' setting. */
206    private CheckBox m_pullFirst;
207
208    /** Field for 'Push automatically' setting. */
209    private CheckBox m_pushAutomatically;
210
211    /** Tab sheet. */
212    private TabSheet m_tabs;
213
214    /** Button used to toggle advanced options. */
215    private Button m_toggleOptions;
216
217    /** Current user. */
218    private CmsUser m_user;
219
220    /** The field for the git user name. */
221    private TextField m_userField;
222
223    /**
224     * Creates a new instance.<p>
225     *
226     * @param checkinBean the bean to be used for the check-in operation.
227     */
228    public CmsGitToolOptionsPanel(CmsGitCheckin checkinBean) {
229
230        m_checkinBean = checkinBean;
231        if (!checkinBean.hasValidConfiguration()) {
232            setMargin(true);
233            Label errorLabel = new Label(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_APP_UNCONFIGURED_0));
234            errorLabel.setContentMode(ContentMode.HTML);
235            addComponent(errorLabel);
236            return;
237        }
238        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
239        configureConfigurationSelector();
240        updateForNewConfiguration(m_checkinBean.getCurrentConfiguration());
241
242        m_user = A_CmsUI.getCmsObject().getRequestContext().getCurrentUser();
243        restoreFieldsFromUserInfo();
244
245        setAdvancedVisible(false);
246        m_toggleOptions.addClickListener(new ClickListener() {
247
248            private static final long serialVersionUID = 1L;
249
250            public void buttonClick(ClickEvent event) {
251
252                setAdvancedVisible(!m_advancedVisible);
253            }
254        });
255        m_okButton.addClickListener(new ClickListener() {
256
257            private static final long serialVersionUID = 1L;
258
259            @SuppressWarnings("synthetic-access")
260            public void buttonClick(ClickEvent event) {
261
262                if (m_dialogTab == DialogTab.checkIn) {
263                    runAction(ActionType.checkIn);
264                } else {
265                    runAction(ActionType.checkOut);
266                }
267            }
268        });
269        m_cancel.addClickListener(new ClickListener() {
270
271            private static final long serialVersionUID = 1L;
272
273            public void buttonClick(ClickEvent event) {
274
275                A_CmsUI.get().getPage().setLocation(CmsVaadinUtils.getWorkplaceLink());
276            }
277        });
278        m_deselectAll.addClickListener(new ClickListener() {
279
280            private static final long serialVersionUID = 1L;
281
282            public void buttonClick(ClickEvent event) {
283
284                for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
285                    CheckBox checkBox = entry.getValue();
286                    checkBox.setValue(Boolean.FALSE);
287                }
288            }
289        });
290
291        m_tabs.addStyleName(ValoTheme.TABSHEET_FRAMED);
292        m_tabs.addStyleName(ValoTheme.TABSHEET_PADDED_TABBAR);
293        m_tabs.addSelectedTabChangeListener(new SelectedTabChangeListener() {
294
295            private static final long serialVersionUID = 1L;
296
297            @SuppressWarnings("synthetic-access")
298            public void selectedTabChange(SelectedTabChangeEvent event) {
299
300                DialogTab tab;
301                if (m_tabs.getSelectedTab() == m_checkoutTab) {
302                    tab = DialogTab.checkOut;
303                } else {
304                    tab = DialogTab.checkIn;
305                }
306                CmsGitToolOptionsPanel.this.setTab(tab);
307
308            }
309
310        });
311        m_fetchAndReset.setValue(Boolean.TRUE);
312        setTab(m_dialogTab);
313    }
314
315    /**
316     * Opens a modal window with the given component as content.<p>
317     *
318     * @param component the window content
319     *
320     * @return the window which is opened
321     */
322    public Window addAsWindow(Component component) {
323
324        // Have to use an array because Vaadin declarative tries to bind the field otherwise
325        if (m_currentWindow[0] != null) {
326            m_currentWindow[0].close();
327            m_currentWindow[0] = null;
328        }
329
330        Window window = new Window();
331        window.setContent(component);
332        window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_SCRIPT_RESULTS_0));
333        window.setWidth("1000px");
334        window.setModal(true);
335        window.setResizable(false);
336        A_CmsUI.get().addWindow(window);
337
338        m_currentWindow[0] = window;
339        return window;
340    }
341
342    /**
343     * Adds a check box and info widget for a module which should be selectable for check-in.<p>
344     *
345     * @param moduleName the name of the module
346     */
347    public void addSelectableModule(final String moduleName) {
348
349        boolean enabled = true; /* OpenCms.getModuleManager().hasModule(moduleName); */
350        CheckBox moduleCheckBox = new CheckBox();
351        String iconUri = CmsWorkplace.getResourceUri("tools/modules/buttons/modules.png");
352        CmsResourceInfo info = new CmsResourceInfo(moduleName, "", iconUri);
353        HorizontalLayout line = new HorizontalLayout();
354        line.setWidth("100%");
355        line.addComponent(moduleCheckBox);
356        info.setWidth("100%");
357        line.addComponent(info);
358        line.setComponentAlignment(moduleCheckBox, Alignment.MIDDLE_CENTER);
359        line.setExpandRatio(info, 1.0f);
360        moduleCheckBox.setEnabled(true);
361        moduleCheckBox.setValue(Boolean.valueOf(enabled)); // If enabled, then checked by default
362        m_moduleCheckboxes.put(moduleName, moduleCheckBox);
363        m_moduleSelectionContainer.addComponent(line, m_moduleSelectionContainer.getComponentCount() - 1);
364        setTab(m_dialogTab);
365    }
366
367    /**
368     * Enables/disables checkboxes for listed modules which are not installed.<p>
369     *
370     * @param enable true if the checkboxes for modules which are not installed should be enabled, false if they should be disabled
371     */
372    public void enableCheckboxesForNotInstalledModules(boolean enable) {
373
374        for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
375            String moduleName = entry.getKey();
376            CheckBox checkbox = entry.getValue();
377            if (!OpenCms.getModuleManager().hasModule(moduleName)) {
378                checkbox.setEnabled(enable);
379                if (!enable) {
380                    checkbox.setValue(Boolean.FALSE);
381                }
382            }
383        }
384    }
385
386    /**
387     * Gets the modules which are selected for check-in.<p>
388     *
389     * @return the selected modules
390     */
391    public Collection<String> getSelectedModules() {
392
393        List<String> result = Lists.newArrayList();
394        for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
395            if (entry.getValue().getValue().booleanValue()) {
396                result.add(entry.getKey());
397            }
398        }
399        return result;
400    }
401
402    /**
403     * Executes one of the dialog actions.<p>
404     *
405     * @param action the action to perform
406     */
407    public void runAction(ActionType action) {
408
409        m_mode = action;
410        setActionFlags();
411        setCommonParameters();
412        m_checkinBean.clearModules();
413        for (String moduleName : getSelectedModules()) {
414            m_checkinBean.addModuleToExport(moduleName);
415        }
416        int result = m_checkinBean.checkIn();
417        String log = m_checkinBean.getLogText();
418        String message = null;
419        boolean error = false;
420        switch (action) {
421            case checkIn:
422                String messageToSave = m_checkinBean.getCommitMessage();
423                String emailToSave = m_checkinBean.getGitUserEmail();
424                String userToSave = m_checkinBean.getGitUserName();
425                CmsObject cms = m_checkinBean.getCmsObject();
426                CmsUser user = cms.getRequestContext().getCurrentUser();
427                setUserInfo(user, ADDINFO_USER, userToSave);
428                setUserInfo(user, ADDINFO_EMAIL, emailToSave);
429                setUserInfo(user, ADDINFO_MESSAGE, messageToSave);
430                try {
431                    cms.writeUser(user);
432                } catch (CmsException e) {
433                    LOG.error(e.getLocalizedMessage(), e);
434                }
435
436                List<Button> resetButtons = new ArrayList<Button>();
437
438                Button resetHead = new Button(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_HEAD_0));
439                resetHead.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_HEAD_DESC_0));
440                resetHead.addClickListener(new ClickListener() {
441
442                    private static final long serialVersionUID = 1L;
443
444                    public void buttonClick(ClickEvent event) {
445
446                        runAction(ActionType.resetHead);
447                    }
448                });
449
450                Button resetRemoteHead = new Button(
451                    CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_REMOTE_HEAD_0));
452                resetRemoteHead.setDescription(
453                    CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_REMOTE_HEAD_DESC_0));
454                resetRemoteHead.addClickListener(new ClickListener() {
455
456                    private static final long serialVersionUID = 1L;
457
458                    public void buttonClick(ClickEvent event) {
459
460                        runAction(ActionType.resetRemoteHead);
461                    }
462                });
463
464                if (result == 0) {
465                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_SUCCESSFUL_0);
466                } else if (result == 10) {
467                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_FAILED_0);
468                    error = true;
469                    resetButtons.add(resetRemoteHead);
470                    resetButtons.add(resetHead);
471                } else {
472                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_FAILED_0);
473                    error = true;
474                    resetButtons.add(resetRemoteHead);
475                }
476                CmsGitActionResultPanel panel = new CmsGitActionResultPanel(message, log, error, resetButtons);
477                addAsWindow(panel);
478                break;
479            case checkOut:
480                if (result == 0) {
481                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_IMPORT_SUCCESSFUL_0);
482                } else {
483                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_IMPORT_FAILED_0);
484                }
485                CmsGitActionResultPanel checkoutResult = new CmsGitActionResultPanel(
486                    message,
487                    log,
488                    error,
489                    new ArrayList<Button>());
490                addAsWindow(checkoutResult);
491                break;
492            case resetHead:
493                if (result == 0) {
494                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_SUCCESSFUL_0);
495                } else {
496                    error = true;
497                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_FAILED_0);
498                }
499                CmsGitActionResultPanel resetResult = new CmsGitActionResultPanel(
500                    message,
501                    log,
502                    error,
503                    new ArrayList<Button>());
504                addAsWindow(resetResult);
505                break;
506            case resetRemoteHead:
507                if (result == 0) {
508                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_SUCCESSFUL_0);
509                } else {
510                    error = true;
511                    message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_FAILED_0);
512                }
513                CmsGitActionResultPanel resetRemoteResult = new CmsGitActionResultPanel(
514                    message,
515                    log,
516                    error,
517                    new ArrayList<Button>());
518                addAsWindow(resetRemoteResult);
519                break;
520            default:
521                // Should never happen
522        }
523    }
524
525    /**
526     * Sets the flags for the current action.<p>
527     */
528    public void setActionFlags() {
529
530        m_checkinBean.setFetchAndResetBeforeImport(m_fetchAndReset.getValue().booleanValue());
531        switch (m_mode) {
532            case checkOut:
533                m_checkinBean.setCheckout(true);
534                m_checkinBean.setResetHead(false);
535                m_checkinBean.setResetRemoteHead(false);
536                break;
537            case checkIn:
538                m_checkinBean.setCheckout(false);
539                m_checkinBean.setResetHead(false);
540                m_checkinBean.setResetRemoteHead(false);
541                break;
542            case resetHead:
543                m_checkinBean.setCheckout(false);
544                m_checkinBean.setResetHead(true);
545                m_checkinBean.setResetRemoteHead(false);
546                break;
547            case resetRemoteHead:
548                m_checkinBean.setCheckout(false);
549                m_checkinBean.setResetHead(false);
550                m_checkinBean.setResetRemoteHead(true);
551                break;
552            default:
553                break;
554        }
555
556    }
557
558    /**
559     * Changes visibility of the advanced options.<p>
560     *
561     * @param visible true if the options should be shown
562     */
563    public void setAdvancedVisible(boolean visible) {
564
565        m_advancedLayout.setVisible(visible);
566        m_advancedVisible = visible;
567        m_toggleOptions.setCaption(
568            visible
569            ? CmsVaadinUtils.getMessageText(Messages.GUI_GIT_OPTIONS_HIDE_0)
570            : CmsVaadinUtils.getMessageText(Messages.GUI_GIT_OPTIONS_SHOW_0));
571    }
572
573    /**
574     * Called when the active tab is switched.<p>
575     *
576     * @param dialogTab the dialog tab to which the user has switched
577     */
578    public void setTab(DialogTab dialogTab) {
579
580        m_dialogTab = dialogTab;
581        switch (dialogTab) {
582            case checkIn:
583                enableCheckboxesForNotInstalledModules(false);
584                m_okButton.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_CHECK_IN_0));
585                break;
586            case checkOut:
587                m_fakeEmailField.setValue(m_emailField.getValue());
588                m_fakeUserField.setValue(m_userField.getValue());
589                m_okButton.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_IMPORT_0));
590                enableCheckboxesForNotInstalledModules(true);
591                break;
592            default:
593                break;
594        }
595    }
596
597    /**
598     * Updates the selection widget for adding new modules.<p>
599     */
600    public void updateNewModuleSelector() {
601
602        ComboBox newModuleSelector = createModuleSelector();
603        ((AbstractLayout)(m_moduleSelector.getParent())).replaceComponent(m_moduleSelector, newModuleSelector);
604        m_moduleSelector = newModuleSelector;
605        m_moduleSelector.addValueChangeListener(new ValueChangeListener() {
606
607            private static final long serialVersionUID = 1L;
608
609            public void valueChange(ValueChangeEvent event) {
610
611                String moduleName = (String)(event.getProperty().getValue());
612                addSelectableModule(moduleName);
613                updateNewModuleSelector();
614            }
615        });
616    }
617
618    /**
619     * Updates the options panel for a special configuration.
620     * @param gitConfig the git configuration.
621     */
622    protected void updateForNewConfiguration(CmsGitConfiguration gitConfig) {
623
624        if (!m_checkinBean.setCurrentConfiguration(gitConfig)) {
625            Notification.show(
626                CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CONFIGURATION_SWITCH_FAILED_0),
627                CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CONFIGURATION_SWITCH_FAILED_DESC_0),
628                Type.ERROR_MESSAGE);
629            m_configurationSelector.select(m_checkinBean.getCurrentConfiguration());
630            return;
631        }
632
633        resetSelectableModules();
634        for (final String moduleName : gitConfig.getConfiguredModules()) {
635            addSelectableModule(moduleName);
636        }
637        updateNewModuleSelector();
638        m_pullFirst.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPullBefore()));
639        m_pullAfterCommit.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPullAfter()));
640        m_addAndCommit.setValue(Boolean.valueOf(gitConfig.getDefaultAutoCommit()));
641        m_pushAutomatically.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPush()));
642        m_commitMessage.setValue(Strings.nullToEmpty(gitConfig.getDefaultCommitMessage()));
643        m_copyAndUnzip.setValue(Boolean.valueOf(gitConfig.getDefaultCopyAndUnzip()));
644        m_excludeLib.setValue(Boolean.valueOf(gitConfig.getDefaultExcludeLibs()));
645        m_ignoreUnclean.setValue(Boolean.valueOf(gitConfig.getDefaultIngoreUnclean()));
646        m_userField.setValue(Strings.nullToEmpty(gitConfig.getDefaultGitUserName()));
647        m_emailField.setValue(Strings.nullToEmpty(gitConfig.getDefaultGitUserEmail()));
648
649    }
650
651    /**
652     * Configures the configuration selector.
653     */
654    private void configureConfigurationSelector() {
655
656        if (m_checkinBean.getConfigurations().size() < 2) {
657            // Do not show the configuration selection at all.
658            removeComponent(m_configurationSelectionPanel);
659        } else {
660            for (CmsGitConfiguration configuration : m_checkinBean.getConfigurations()) {
661                m_configurationSelector.addItem(configuration);
662                m_configurationSelector.setItemCaption(configuration, configuration.getName());
663            }
664            m_configurationSelector.setNullSelectionAllowed(false);
665            m_configurationSelector.setNewItemsAllowed(false);
666            m_configurationSelector.setWidth("350px");
667            m_configurationSelector.select(m_checkinBean.getCurrentConfiguration());
668
669            // There is really a choice between configurations
670            m_configurationSelector.addValueChangeListener(new ValueChangeListener() {
671
672                private static final long serialVersionUID = 1L;
673
674                @SuppressWarnings("synthetic-access")
675                public void valueChange(ValueChangeEvent event) {
676
677                    updateForNewConfiguration((CmsGitConfiguration)event.getProperty().getValue());
678                    restoreFieldsFromUserInfo();
679
680                }
681            });
682        }
683    }
684
685    /**
686     * Creates a new module selector, containing only the modules for which no check box is already displayed.<p>
687     *
688     * @return the new module selector
689     */
690    private ComboBox createModuleSelector() {
691
692        ComboBox result = new ComboBox();
693        result.setPageLength(20);
694        result.setWidth("350px");
695        result.setFilteringMode(FilteringMode.CONTAINS);
696        result.setNewItemsAllowed(false);
697        result.setNullSelectionAllowed(false);
698        List<String> moduleNames = Lists.newArrayList();
699        for (CmsModule module : OpenCms.getModuleManager().getAllInstalledModules()) {
700            String moduleName = module.getName();
701            if (!m_moduleCheckboxes.containsKey(moduleName)) {
702                moduleNames.add(moduleName);
703            }
704        }
705        Collections.sort(moduleNames);
706        for (String moduleName : moduleNames) {
707            result.addItem(moduleName);
708        }
709
710        return result;
711    }
712
713    /**
714     * Removes all currently selectable modules.
715     */
716    private void resetSelectableModules() {
717
718        m_moduleCheckboxes.clear();
719
720        m_moduleSelectionContainer.removeAllComponents();
721        m_moduleSelectionContainer.addComponent(m_moduleSelectorContainer);
722
723    }
724
725    /**
726     * Restores user/email/message input fields from saved values.<p>
727     */
728    private void restoreFieldsFromUserInfo() {
729
730        String savedEmail = (String)(m_user.getAdditionalInfo().get(ADDINFO_EMAIL));
731        String savedName = (String)(m_user.getAdditionalInfo().get(ADDINFO_USER));
732        String savedMessage = (String)(m_user.getAdditionalInfo().get(ADDINFO_MESSAGE));
733
734        if (savedEmail != null) {
735            m_emailField.setValue(savedEmail);
736        }
737
738        if (savedName != null) {
739            m_userField.setValue(savedName);
740        }
741
742        if (savedMessage != null) {
743            m_commitMessage.setValue(savedMessage);
744        }
745    }
746
747    /**
748     * Transfers the parameters from the form to the check-in bean.<p>
749     */
750    private void setCommonParameters() {
751
752        m_checkinBean.setPullBefore(m_pullFirst.getValue().booleanValue());
753        m_checkinBean.setPullAfter(m_pullAfterCommit.getValue().booleanValue());
754        m_checkinBean.setPush(m_pushAutomatically.getValue().booleanValue());
755        m_checkinBean.setExcludeLibs(m_excludeLib.getValue().booleanValue());
756        m_checkinBean.setCommit(m_addAndCommit.getValue().booleanValue());
757        m_checkinBean.setIgnoreUnclean(m_ignoreUnclean.getValue().booleanValue());
758        m_checkinBean.setCopyAndUnzip(m_copyAndUnzip.getValue().booleanValue());
759        m_checkinBean.setGitUserEmail(m_emailField.getValue());
760        m_checkinBean.setGitUserName(m_userField.getValue());
761        String commitMessage = m_commitMessage.getValue();
762        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(commitMessage)) {
763            m_checkinBean.setCommitMessage(commitMessage);
764        }
765    }
766
767    /**
768     * Sets an additional info value if it's not empty.<p>
769     *
770     * @param user the user on which to set the additional info
771     * @param key the additional info key
772     * @param value the additional info value
773     */
774    private void setUserInfo(CmsUser user, String key, String value) {
775
776        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
777            user.getAdditionalInfo().put(key, value);
778        }
779    }
780
781}