content: /*
   * This library is part of OpenCms -
   * the Open Source Content Management System
   *
   * Copyright (c) Alkacon Software GmbH & Co. KG (https://www.alkacon.com)
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library 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
   * Lesser General Public License for more details.
   *
   * For further information about Alkacon Software, please see the
   * company website: https://www.alkacon.com
   *
   * For further information about OpenCms, please see the
   * project website: https://www.opencms.org
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
  package org.opencms.ui.apps.git;
  
  import org.opencms.file.CmsObject;
  import org.opencms.file.CmsUser;
  import org.opencms.main.CmsException;
  import org.opencms.main.CmsLog;
  import org.opencms.main.OpenCms;
  import org.opencms.module.CmsModule;
  import org.opencms.ui.A_CmsUI;
  import org.opencms.ui.CmsVaadinUtils;
  import org.opencms.ui.components.CmsResourceInfo;
  import org.opencms.util.CmsStringUtil;
  import org.opencms.workplace.CmsWorkplace;
  
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.List;
  import java.util.Map;
  
  import org.apache.commons.logging.Log;
  
  import com.google.common.base.Strings;
  import com.google.common.collect.Lists;
  import com.google.common.collect.Maps;
  import com.vaadin.v7.data.Property.ValueChangeEvent;
  import com.vaadin.v7.data.Property.ValueChangeListener;
  import com.vaadin.v7.shared.ui.combobox.FilteringMode;
  import com.vaadin.v7.shared.ui.label.ContentMode;
  import com.vaadin.ui.AbstractLayout;
  import com.vaadin.ui.Alignment;
  import com.vaadin.ui.Button;
  import com.vaadin.ui.Button.ClickEvent;
  import com.vaadin.ui.Button.ClickListener;
  import com.vaadin.v7.ui.CheckBox;
  import com.vaadin.v7.ui.ComboBox;
  import com.vaadin.ui.Component;
  import com.vaadin.v7.ui.HorizontalLayout;
  import com.vaadin.v7.ui.Label;
  import com.vaadin.ui.Notification;
  import com.vaadin.ui.Notification.Type;
  import com.vaadin.ui.Panel;
  import com.vaadin.ui.TabSheet;
  import com.vaadin.ui.TabSheet.SelectedTabChangeEvent;
  import com.vaadin.ui.TabSheet.SelectedTabChangeListener;
  import com.vaadin.v7.ui.TextArea;
  import com.vaadin.v7.ui.TextField;
  import com.vaadin.v7.ui.VerticalLayout;
  import com.vaadin.ui.Window;
  import com.vaadin.ui.themes.ValoTheme;
  
  /**
   * Main widget for the Git check-in tool.<p>
   */
  public class CmsGitToolOptionsPanel extends VerticalLayout {
  
      /**
       * Enum describing the type of action to perform.<p>
       */
      enum ActionType {
          /** Check in. */
          checkIn,
  
          /** Checkout action. */
          checkOut,
  
          /** Reset to HEAD. */
          resetHead,
  
          /** Reset to remote head. */
          resetRemoteHead;
      }
  
      /**
       * Enum representing the dialog's tabs.
       */
      enum DialogTab {
          /** The 'check in' tab. */
          checkIn,
  
          /** The 'import' tab. */
          checkOut;
      }
  
      /** Additional info key for the email address. */
      public static final String ADDINFO_EMAIL = "git_cms_email";
  
      /** Additional info key for the commit message. */
      public static final String ADDINFO_MESSAGE = "git_cms_message";
  
      /** Additional info key for the user name. */
      public static final String ADDINFO_USER = "git_cms_user";
  
      /** Logger instance for this class. */
      private static final Log LOG = CmsLog.getLog(CmsGitToolOptionsPanel.class);
  
      /** Serial version id. */
      private static final long serialVersionUID = 1L;
  
      /** True when advanced options are currently visible. */
      protected boolean m_advancedVisible;
  
      /** Map of check boxes for selectable modules, with the module names as keys. */
      Map<String, CheckBox> m_moduleCheckboxes = Maps.newHashMap();
  
      /** Field for 'Add and commit' setting. */
      private CheckBox m_addAndCommit;
  
      /** The advanced options layout. */
      private VerticalLayout m_advancedLayout;
  
      /** Cancel button. */
      private Button m_cancel;
  
      /** The check-in bean. */
      private CmsGitCheckin m_checkinBean;
  
      /** The tab with the import settings. */
      private Component m_checkoutTab;
  
      /** Field for 'Commit message' setting. */
      private TextArea m_commitMessage;
  
      /** Panel for the configuration selection. */
      private Panel m_configurationSelectionPanel;
  
      /** Configuration selector. */
      private ComboBox m_configurationSelector;
  
      /** Field for 'Copy and unzip' setting. */
      private CheckBox m_copyAndUnzip;
  
      /** Current window (using an array so the Vaadin field binder doesn't process this. */
      private Window[] m_currentWindow = new Window[] {null};
  
      /** Button for deselecting all modules. */
      private Button m_deselectAll;
  
      /** The initial dialog tab. */
      private DialogTab m_dialogTab = DialogTab.checkIn;
  
      /** The field for the email address. */
      private TextField m_emailField;
  
      /** Field for 'Exclude lib' setting. */
      private CheckBox m_excludeLib;
  
      /** Email field for module import. */
      private TextField m_fakeEmailField;
  
      /** User field for module import. */
      private TextField m_fakeUserField;
  
      /** Checkbox for the 'fetch and reset' option. */
      private CheckBox m_fetchAndReset;
  
      /** Field for 'Ignroe unclean' setting. */
      private CheckBox m_ignoreUnclean;
  
      /** Selected mode. */
      private ActionType m_mode = ActionType.checkIn;
  
      /** Container for the module selector. */
      private VerticalLayout m_moduleSelectionContainer;
  
      /** Module selector. */
      private ComboBox m_moduleSelector;
  
      /** Container for the module selector drop-down and the "Deselect all" button. */
      private HorizontalLayout m_moduleSelectorContainer;
  
      /** Button for check-in. */
      private Button m_okButton;
  
      /** Field for 'Pull after commit' setting. */
      private CheckBox m_pullAfterCommit;
  
      /** Field for 'Pull first' setting. */
      private CheckBox m_pullFirst;
  
      /** Field for 'Push automatically' setting. */
      private CheckBox m_pushAutomatically;
  
      /** Tab sheet. */
      private TabSheet m_tabs;
  
      /** Button used to toggle advanced options. */
      private Button m_toggleOptions;
  
      /** Current user. */
      private CmsUser m_user;
  
      /** The field for the git user name. */
      private TextField m_userField;
  
      /**
       * Creates a new instance.<p>
       *
       * @param checkinBean the bean to be used for the check-in operation.
       */
      public CmsGitToolOptionsPanel(CmsGitCheckin checkinBean) {
          m_checkinBean = checkinBean;
          if (!checkinBean.hasValidConfiguration()) {
              setMargin(true);
              Label errorLabel = new Label(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_APP_UNCONFIGURED_0));
              errorLabel.setContentMode(ContentMode.HTML);
              addComponent(errorLabel);
              return;
          }
          CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
          configureConfigurationSelector();
          updateForNewConfiguration(m_checkinBean.getCurrentConfiguration());
  
          m_user = A_CmsUI.getCmsObject().getRequestContext().getCurrentUser();
          restoreFieldsFromUserInfo();
  
          setAdvancedVisible(false);
          m_toggleOptions.addClickListener(new ClickListener() {
  
              private static final long serialVersionUID = 1L;
  
              public void buttonClick(ClickEvent event) {
  
                  setAdvancedVisible(!m_advancedVisible);
              }
          });
          m_okButton.addClickListener(new ClickListener() {
  
              private static final long serialVersionUID = 1L;
  
              @SuppressWarnings("synthetic-access")
              public void buttonClick(ClickEvent event) {
  
                  if (m_dialogTab == DialogTab.checkIn) {
                      runAction(ActionType.checkIn);
                  } else {
                      runAction(ActionType.checkOut);
                  }
              }
          });
          m_cancel.addClickListener(new ClickListener() {
  
              private static final long serialVersionUID = 1L;
  
              public void buttonClick(ClickEvent event) {
  
                  A_CmsUI.get().getPage().setLocation(CmsVaadinUtils.getWorkplaceLink());
              }
          });
          m_deselectAll.addClickListener(new ClickListener() {
  
              private static final long serialVersionUID = 1L;
  
              public void buttonClick(ClickEvent event) {
  
                  for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
                      CheckBox checkBox = entry.getValue();
                      checkBox.setValue(Boolean.FALSE);
                  }
              }
          });
  
          m_tabs.addStyleName(ValoTheme.TABSHEET_FRAMED);
          m_tabs.addStyleName(ValoTheme.TABSHEET_PADDED_TABBAR);
          m_tabs.addSelectedTabChangeListener(new SelectedTabChangeListener() {
  
              private static final long serialVersionUID = 1L;
  
              @SuppressWarnings("synthetic-access")
              public void selectedTabChange(SelectedTabChangeEvent event) {
  
                  DialogTab tab;
                  if (m_tabs.getSelectedTab() == m_checkoutTab) {
                      tab = DialogTab.checkOut;
                  } else {
                      tab = DialogTab.checkIn;
                  }
                  CmsGitToolOptionsPanel.this.setTab(tab);
  
              }
  
          });
          m_fetchAndReset.setValue(Boolean.TRUE);
          setTab(m_dialogTab);
      }
  
      /**
       * Opens a modal window with the given component as content.<p>
       *
       * @param component the window content
       *
       * @return the window which is opened
       */
      public Window addAsWindow(Component component) {
  
          // Have to use an array because Vaadin declarative tries to bind the field otherwise
          if (m_currentWindow[0] != null) {
              m_currentWindow[0].close();
              m_currentWindow[0] = null;
          }
  
          Window window = new Window();
          window.setContent(component);
          window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_SCRIPT_RESULTS_0));
          window.setWidth("1000px");
          window.setModal(true);
          window.setResizable(false);
          A_CmsUI.get().addWindow(window);
  
          m_currentWindow[0] = window;
          return window;
      }
  
      /**
       * Adds a check box and info widget for a module which should be selectable for check-in.<p>
       *
       * @param moduleName the name of the module
       */
      public void addSelectableModule(final String moduleName) {
  
          boolean enabled = true; /* OpenCms.getModuleManager().hasModule(moduleName); */
          CheckBox moduleCheckBox = new CheckBox();
          String iconUri = CmsWorkplace.getResourceUri("tools/modules/buttons/modules.png");
          CmsResourceInfo info = new CmsResourceInfo(moduleName, "", iconUri);
          HorizontalLayout line = new HorizontalLayout();
          line.setWidth("100%");
          line.addComponent(moduleCheckBox);
          info.setWidth("100%");
          line.addComponent(info);
          line.setComponentAlignment(moduleCheckBox, Alignment.MIDDLE_CENTER);
          line.setExpandRatio(info, 1.0f);
          moduleCheckBox.setEnabled(true);
          moduleCheckBox.setValue(Boolean.valueOf(enabled)); // If enabled, then checked by default
          m_moduleCheckboxes.put(moduleName, moduleCheckBox);
          m_moduleSelectionContainer.addComponent(line, m_moduleSelectionContainer.getComponentCount() - 1);
          setTab(m_dialogTab);
      }
  
      /**
       * Enables/disables checkboxes for listed modules which are not installed.<p>
       *
       * @param enable true if the checkboxes for modules which are not installed should be enabled, false if they should be disabled
       */
      public void enableCheckboxesForNotInstalledModules(boolean enable) {
  
          for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
              String moduleName = entry.getKey();
              CheckBox checkbox = entry.getValue();
              if (!OpenCms.getModuleManager().hasModule(moduleName)) {
                  checkbox.setEnabled(enable);
                  if (!enable) {
                      checkbox.setValue(Boolean.FALSE);
                  }
              }
          }
      }
  
      /**
       * Gets the modules which are selected for check-in.<p>
       *
       * @return the selected modules
       */
      public Collection<String> getSelectedModules() {
  
          List<String> result = Lists.newArrayList();
          for (Map.Entry<String, CheckBox> entry : m_moduleCheckboxes.entrySet()) {
              if (entry.getValue().getValue().booleanValue()) {
                  result.add(entry.getKey());
              }
          }
          return result;
      }
  
      /**
       * Executes one of the dialog actions.<p>
       *
       * @param action the action to perform
       */
      public void runAction(ActionType action) {
  
          m_mode = action;
          setActionFlags();
          setCommonParameters();
          m_checkinBean.clearModules();
          for (String moduleName : getSelectedModules()) {
              m_checkinBean.addModuleToExport(moduleName);
          }
          int result = m_checkinBean.checkIn();
          String log = m_checkinBean.getLogText();
          String message = null;
          boolean error = false;
          switch (action) {
              case checkIn:
                  String messageToSave = m_checkinBean.getCommitMessage();
                  String emailToSave = m_checkinBean.getGitUserEmail();
                  String userToSave = m_checkinBean.getGitUserName();
                  CmsObject cms = m_checkinBean.getCmsObject();
                  CmsUser user = cms.getRequestContext().getCurrentUser();
                  setUserInfo(user, ADDINFO_USER, userToSave);
                  setUserInfo(user, ADDINFO_EMAIL, emailToSave);
                  setUserInfo(user, ADDINFO_MESSAGE, messageToSave);
                  try {
                      cms.writeUser(user);
                  } catch (CmsException e) {
                      LOG.error(e.getLocalizedMessage(), e);
                  }
  
                  List<Button> resetButtons = new ArrayList<Button>();
  
                  Button resetHead = new Button(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_HEAD_0));
                  resetHead.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_HEAD_DESC_0));
                  resetHead.addClickListener(new ClickListener() {
  
                      private static final long serialVersionUID = 1L;
  
                      public void buttonClick(ClickEvent event) {
  
                          runAction(ActionType.resetHead);
                      }
                  });
  
                  Button resetRemoteHead = new Button(
                      CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_REMOTE_HEAD_0));
                  resetRemoteHead.setDescription(
                      CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_RESET_REMOTE_HEAD_DESC_0));
                  resetRemoteHead.addClickListener(new ClickListener() {
  
                      private static final long serialVersionUID = 1L;
  
                      public void buttonClick(ClickEvent event) {
  
                          runAction(ActionType.resetRemoteHead);
                      }
                  });
  
                  if (result == 0) {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_SUCCESSFUL_0);
                  } else if (result == 10) {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_FAILED_0);
                      error = true;
                      resetButtons.add(resetRemoteHead);
                      resetButtons.add(resetHead);
                  } else {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CHECKIN_FAILED_0);
                      error = true;
                      resetButtons.add(resetRemoteHead);
                  }
                  CmsGitActionResultPanel panel = new CmsGitActionResultPanel(message, log, error, resetButtons);
                  addAsWindow(panel);
                  break;
              case checkOut:
                  if (result == 0) {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_IMPORT_SUCCESSFUL_0);
                  } else {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_IMPORT_FAILED_0);
                  }
                  CmsGitActionResultPanel checkoutResult = new CmsGitActionResultPanel(
                      message,
                      log,
                      error,
                      new ArrayList<Button>());
                  addAsWindow(checkoutResult);
                  break;
              case resetHead:
                  if (result == 0) {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_SUCCESSFUL_0);
                  } else {
                      error = true;
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_FAILED_0);
                  }
                  CmsGitActionResultPanel resetResult = new CmsGitActionResultPanel(
                      message,
                      log,
                      error,
                      new ArrayList<Button>());
                  addAsWindow(resetResult);
                  break;
              case resetRemoteHead:
                  if (result == 0) {
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_SUCCESSFUL_0);
                  } else {
                      error = true;
                      message = CmsVaadinUtils.getMessageText(Messages.GUI_GIT_RESET_FAILED_0);
                  }
                  CmsGitActionResultPanel resetRemoteResult = new CmsGitActionResultPanel(
                      message,
                      log,
                      error,
                      new ArrayList<Button>());
                  addAsWindow(resetRemoteResult);
                  break;
              default:
                  // Should never happen
          }
      }
  
      /**
       * Sets the flags for the current action.<p>
       */
      public void setActionFlags() {
  
          m_checkinBean.setFetchAndResetBeforeImport(m_fetchAndReset.getValue().booleanValue());
          switch (m_mode) {
              case checkOut:
                  m_checkinBean.setCheckout(true);
                  m_checkinBean.setResetHead(false);
                  m_checkinBean.setResetRemoteHead(false);
                  break;
              case checkIn:
                  m_checkinBean.setCheckout(false);
                  m_checkinBean.setResetHead(false);
                  m_checkinBean.setResetRemoteHead(false);
                  break;
              case resetHead:
                  m_checkinBean.setCheckout(false);
                  m_checkinBean.setResetHead(true);
                  m_checkinBean.setResetRemoteHead(false);
                  break;
              case resetRemoteHead:
                  m_checkinBean.setCheckout(false);
                  m_checkinBean.setResetHead(false);
                  m_checkinBean.setResetRemoteHead(true);
                  break;
              default:
                  break;
          }
  
      }
  
      /**
       * Changes visibility of the advanced options.<p>
       *
       * @param visible true if the options should be shown
       */
      public void setAdvancedVisible(boolean visible) {
  
          m_advancedLayout.setVisible(visible);
          m_advancedVisible = visible;
          m_toggleOptions.setCaption(
              visible
              ? CmsVaadinUtils.getMessageText(Messages.GUI_GIT_OPTIONS_HIDE_0)
              : CmsVaadinUtils.getMessageText(Messages.GUI_GIT_OPTIONS_SHOW_0));
      }
  
      /**
       * Called when the active tab is switched.<p>
       *
       * @param dialogTab the dialog tab to which the user has switched
       */
      public void setTab(DialogTab dialogTab) {
  
          m_dialogTab = dialogTab;
          switch (dialogTab) {
              case checkIn:
                  enableCheckboxesForNotInstalledModules(false);
                  m_okButton.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_CHECK_IN_0));
                  break;
              case checkOut:
                  m_fakeEmailField.setValue(m_emailField.getValue());
                  m_fakeUserField.setValue(m_userField.getValue());
                  m_okButton.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_GIT_BUTTON_IMPORT_0));
                  enableCheckboxesForNotInstalledModules(true);
                  break;
              default:
                  break;
          }
      }
  
      /**
       * Updates the selection widget for adding new modules.<p>
       */
      public void updateNewModuleSelector() {
  
          ComboBox newModuleSelector = createModuleSelector();
          ((AbstractLayout)(m_moduleSelector.getParent())).replaceComponent(m_moduleSelector, newModuleSelector);
          m_moduleSelector = newModuleSelector;
          m_moduleSelector.addValueChangeListener(new ValueChangeListener() {
  
              private static final long serialVersionUID = 1L;
  
              public void valueChange(ValueChangeEvent event) {
  
                  String moduleName = (String)(event.getProperty().getValue());
                  addSelectableModule(moduleName);
                  updateNewModuleSelector();
              }
          });
      }
  
      /**
       * Updates the options panel for a special configuration.
       * @param gitConfig the git configuration.
       */
      protected void updateForNewConfiguration(CmsGitConfiguration gitConfig) {
  
          if (!m_checkinBean.setCurrentConfiguration(gitConfig)) {
              Notification.show(
                  CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CONFIGURATION_SWITCH_FAILED_0),
                  CmsVaadinUtils.getMessageText(Messages.GUI_GIT_CONFIGURATION_SWITCH_FAILED_DESC_0),
                  Type.ERROR_MESSAGE);
              m_configurationSelector.select(m_checkinBean.getCurrentConfiguration());
              return;
          }
  
          resetSelectableModules();
          for (final String moduleName : gitConfig.getConfiguredModules()) {
              addSelectableModule(moduleName);
          }
          updateNewModuleSelector();
          m_pullFirst.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPullBefore()));
          m_pullAfterCommit.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPullAfter()));
          m_addAndCommit.setValue(Boolean.valueOf(gitConfig.getDefaultAutoCommit()));
          m_pushAutomatically.setValue(Boolean.valueOf(gitConfig.getDefaultAutoPush()));
          m_commitMessage.setValue(Strings.nullToEmpty(gitConfig.getDefaultCommitMessage()));
          m_copyAndUnzip.setValue(Boolean.valueOf(gitConfig.getDefaultCopyAndUnzip()));
          m_excludeLib.setValue(Boolean.valueOf(gitConfig.getDefaultExcludeLibs()));
          m_ignoreUnclean.setValue(Boolean.valueOf(gitConfig.getDefaultIngoreUnclean()));
          m_userField.setValue(Strings.nullToEmpty(gitConfig.getDefaultGitUserName()));
          m_emailField.setValue(Strings.nullToEmpty(gitConfig.getDefaultGitUserEmail()));
  
      }
  
      /**
       * Configures the configuration selector.
       */
      private void configureConfigurationSelector() {
  
          if (m_checkinBean.getConfigurations().size() < 2) {
              // Do not show the configuration selection at all.
              removeComponent(m_configurationSelectionPanel);
          } else {
              for (CmsGitConfiguration configuration : m_checkinBean.getConfigurations()) {
                  m_configurationSelector.addItem(configuration);
                  m_configurationSelector.setItemCaption(configuration, configuration.getName());
              }
              m_configurationSelector.setNullSelectionAllowed(false);
              m_configurationSelector.setNewItemsAllowed(false);
              m_configurationSelector.setWidth("350px");
              m_configurationSelector.select(m_checkinBean.getCurrentConfiguration());
  
              // There is really a choice between configurations
              m_configurationSelector.addValueChangeListener(new ValueChangeListener() {
  
                  private static final long serialVersionUID = 1L;
  
                  @SuppressWarnings("synthetic-access")
                  public void valueChange(ValueChangeEvent event) {
  
                      updateForNewConfiguration((CmsGitConfiguration)event.getProperty().getValue());
                      restoreFieldsFromUserInfo();
  
                  }
              });
          }
      }
  
      /**
       * Creates a new module selector, containing only the modules for which no check box is already displayed.<p>
       *
       * @return the new module selector
       */
      private ComboBox createModuleSelector() {
  
          ComboBox result = new ComboBox();
          result.setPageLength(20);
          result.setWidth("350px");
          result.setFilteringMode(FilteringMode.CONTAINS);
          result.setNewItemsAllowed(false);
          result.setNullSelectionAllowed(false);
          List<String> moduleNames = Lists.newArrayList();
          for (CmsModule module : OpenCms.getModuleManager().getAllInstalledModules()) {
              String moduleName = module.getName();
              if (!m_moduleCheckboxes.containsKey(moduleName)) {
                  moduleNames.add(moduleName);
              }
          }
          Collections.sort(moduleNames);
          for (String moduleName : moduleNames) {
              result.addItem(moduleName);
          }
  
          return result;
      }
  
      /**
       * Removes all currently selectable modules.
       */
      private void resetSelectableModules() {
  
          m_moduleCheckboxes.clear();
  
          m_moduleSelectionContainer.removeAllComponents();
          m_moduleSelectionContainer.addComponent(m_moduleSelectorContainer);
  
      }
  
      /**
       * Restores user/email/message input fields from saved values.<p>
       */
      private void restoreFieldsFromUserInfo() {
  
          String savedEmail = (String)(m_user.getAdditionalInfo().get(ADDINFO_EMAIL));
          String savedName = (String)(m_user.getAdditionalInfo().get(ADDINFO_USER));
          String savedMessage = (String)(m_user.getAdditionalInfo().get(ADDINFO_MESSAGE));
  
          if (savedEmail != null) {
              m_emailField.setValue(savedEmail);
          }
  
          if (savedName != null) {
              m_userField.setValue(savedName);
          }
  
          if (savedMessage != null) {
              m_commitMessage.setValue(savedMessage);
          }
      }
  
      /**
       * Transfers the parameters from the form to the check-in bean.<p>
       */
      private void setCommonParameters() {
  
          m_checkinBean.setPullBefore(m_pullFirst.getValue().booleanValue());
          m_checkinBean.setPullAfter(m_pullAfterCommit.getValue().booleanValue());
          m_checkinBean.setPush(m_pushAutomatically.getValue().booleanValue());
          m_checkinBean.setExcludeLibs(m_excludeLib.getValue().booleanValue());
          m_checkinBean.setCommit(m_addAndCommit.getValue().booleanValue());
          m_checkinBean.setIgnoreUnclean(m_ignoreUnclean.getValue().booleanValue());
          m_checkinBean.setCopyAndUnzip(m_copyAndUnzip.getValue().booleanValue());
          m_checkinBean.setGitUserEmail(m_emailField.getValue());
          m_checkinBean.setGitUserName(m_userField.getValue());
          String commitMessage = m_commitMessage.getValue();
          if (!CmsStringUtil.isEmptyOrWhitespaceOnly(commitMessage)) {
              m_checkinBean.setCommitMessage(commitMessage);
          }
      }
  
      /**
       * Sets an additional info value if it's not empty.<p>
       *
       * @param user the user on which to set the additional info
       * @param key the additional info key
       * @param value the additional info value
       */
      private void setUserInfo(CmsUser user, String key, String value) {
  
          if (!CmsStringUtil.isEmptyOrWhitespaceOnly(value)) {
              user.getAdditionalInfo().put(key, value);
          }
      }
  
  }
  