/**
   * Updates the user group.
   *
   * @param companyId the primary key of the user group's company
   * @param userGroupId the primary key of the user group
   * @param name the user group's name
   * @param description the user group's description
   * @param serviceContext the service context to be applied (optionally <code>null</code>). Can set
   *     expando bridge attributes for the user group.
   * @return the user group
   */
  @Override
  public UserGroup updateUserGroup(
      long companyId,
      long userGroupId,
      String name,
      String description,
      ServiceContext serviceContext)
      throws PortalException {

    // User group

    validate(userGroupId, companyId, name);

    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(userGroupId);

    userGroup.setName(name);
    userGroup.setDescription(description);
    userGroup.setExpandoBridgeAttributes(serviceContext);

    userGroupPersistence.update(userGroup);

    // Indexer

    Indexer<UserGroup> indexer = IndexerRegistryUtil.nullSafeGetIndexer(UserGroup.class);

    indexer.reindex(userGroup);

    return userGroup;
  }
  public void editUserGroup(ActionRequest actionRequest, ActionResponse actionResponse)
      throws Exception {

    long userGroupId = ParamUtil.getLong(actionRequest, "userGroupId");

    String name = ParamUtil.getString(actionRequest, "name");
    String description = ParamUtil.getString(actionRequest, "description");

    ServiceContext serviceContext =
        ServiceContextFactory.getInstance(UserGroup.class.getName(), actionRequest);

    UserGroup userGroup = null;

    try (ProxyModeThreadLocalCloseable proxyModeThreadLocalCloseable =
        new ProxyModeThreadLocalCloseable()) {

      ProxyModeThreadLocal.setForceSync(true);

      if (userGroupId <= 0) {

        // Add user group

        userGroup = _userGroupService.addUserGroup(name, description, serviceContext);
      } else {

        // Update user group

        userGroup =
            _userGroupService.updateUserGroup(userGroupId, name, description, serviceContext);
      }
    }

    // Layout set prototypes

    long publicLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "publicLayoutSetPrototypeId");
    long privateLayoutSetPrototypeId =
        ParamUtil.getLong(actionRequest, "privateLayoutSetPrototypeId");
    boolean publicLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(actionRequest, "publicLayoutSetPrototypeLinkEnabled");
    boolean privateLayoutSetPrototypeLinkEnabled =
        ParamUtil.getBoolean(actionRequest, "privateLayoutSetPrototypeLinkEnabled");

    if ((privateLayoutSetPrototypeId > 0) || (publicLayoutSetPrototypeId > 0)) {

      SitesUtil.updateLayoutSetPrototypesLinks(
          userGroup.getGroup(),
          publicLayoutSetPrototypeId,
          privateLayoutSetPrototypeId,
          publicLayoutSetPrototypeLinkEnabled,
          privateLayoutSetPrototypeLinkEnabled);
    }
  }
  protected File[] exportLayouts(long userGroupId, Map<String, String[]> parameterMap)
      throws PortalException {

    File[] files = new File[2];

    UserGroup userGroup = userGroupPersistence.findByPrimaryKey(userGroupId);

    User user = userLocalService.getUser(GetterUtil.getLong(PrincipalThreadLocal.getName()));

    Group group = userGroup.getGroup();

    if (userGroup.hasPrivateLayouts()) {
      Map<String, Serializable> exportLayoutSettingsMap =
          ExportImportConfigurationSettingsMapFactory.buildExportLayoutSettingsMap(
              user,
              group.getGroupId(),
              true,
              ExportImportHelperUtil.getAllLayoutIds(group.getGroupId(), true),
              parameterMap);

      ExportImportConfiguration exportImportConfiguration =
          exportImportConfigurationLocalService.addDraftExportImportConfiguration(
              user.getUserId(),
              ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT,
              exportLayoutSettingsMap);

      files[0] = exportImportLocalService.exportLayoutsAsFile(exportImportConfiguration);
    }

    if (userGroup.hasPublicLayouts()) {
      Map<String, Serializable> exportLayoutSettingsMap =
          ExportImportConfigurationSettingsMapFactory.buildExportLayoutSettingsMap(
              user,
              group.getGroupId(),
              false,
              ExportImportHelperUtil.getAllLayoutIds(group.getGroupId(), false),
              parameterMap);

      ExportImportConfiguration exportImportConfiguration =
          exportImportConfigurationLocalService.addDraftExportImportConfiguration(
              user.getUserId(),
              ExportImportConfigurationConstants.TYPE_EXPORT_LAYOUT,
              exportLayoutSettingsMap);

      files[1] = exportImportLocalService.exportLayoutsAsFile(exportImportConfiguration);
    }

    return files;
  }
  @Override
  protected void doImportStagedModel(PortletDataContext portletDataContext, UserGroup userGroup)
      throws Exception {

    long userId = portletDataContext.getUserId(userGroup.getUserUuid());

    ServiceContext serviceContext = portletDataContext.createServiceContext(userGroup);

    UserGroup existingUserGroup =
        fetchStagedModelByUuidAndGroupId(userGroup.getUuid(), portletDataContext.getGroupId());

    if (existingUserGroup == null) {
      existingUserGroup =
          _userGroupLocalService.fetchUserGroup(
              portletDataContext.getCompanyId(), userGroup.getName());
    }

    UserGroup importedUserGroup = null;

    if (existingUserGroup == null) {
      serviceContext.setUuid(userGroup.getUuid());

      importedUserGroup =
          _userGroupLocalService.addUserGroup(
              userId,
              portletDataContext.getCompanyId(),
              userGroup.getName(),
              userGroup.getDescription(),
              serviceContext);
    } else {
      importedUserGroup =
          _userGroupLocalService.updateUserGroup(
              portletDataContext.getCompanyId(),
              existingUserGroup.getUserGroupId(),
              userGroup.getName(),
              userGroup.getDescription(),
              serviceContext);
    }

    portletDataContext.importClassedModel(userGroup, importedUserGroup);
  }
  protected void validate(long userGroupId, long companyId, String name) throws PortalException {

    if (Validator.isNull(name)
        || (name.indexOf(CharPool.COMMA) != -1)
        || (name.indexOf(CharPool.STAR) != -1)) {

      throw new UserGroupNameException();
    }

    if (Validator.isNumber(name) && !PropsValues.USER_GROUPS_NAME_ALLOW_NUMERIC) {

      throw new UserGroupNameException();
    }

    UserGroup userGroup = fetchUserGroup(companyId, name);

    if ((userGroup != null) && (userGroup.getUserGroupId() != userGroupId)) {

      throw new DuplicateUserGroupException("{name=" + name + "}");
    }
  }
  @Override
  public boolean isShow(PortletRequest portletRequest) {
    try {
      ThemeDisplay themeDisplay = (ThemeDisplay) portletRequest.getAttribute(WebKeys.THEME_DISPLAY);

      UserGroup userGroup = ActionUtil.getUserGroup(portletRequest);

      if (UserGroupPermissionUtil.contains(
              themeDisplay.getPermissionChecker(), userGroup.getUserGroupId(), ActionKeys.UPDATE)
          && UserGroupPermissionUtil.contains(
              themeDisplay.getPermissionChecker(), userGroup.getUserGroupId(), ActionKeys.VIEW)) {

        return true;
      }

      return false;
    } catch (Exception e) {
    }

    return false;
  }
  @Override
  public String getURL(PortletRequest portletRequest, PortletResponse portletResponse) {

    try {
      PortletURL portletURL =
          PortletURLFactoryUtil.create(
              portletRequest,
              UserGroupsAdminPortletKeys.USER_GROUPS_ADMIN,
              PortletRequest.RENDER_PHASE);

      portletURL.setParameter("mvcPath", "/edit_user_group.jsp");
      portletURL.setParameter("redirect", PortalUtil.getCurrentURL(portletRequest));

      UserGroup userGroup = ActionUtil.getUserGroup(portletRequest);

      portletURL.setParameter("userGroupId", String.valueOf(userGroup.getUserGroupId()));

      return portletURL.toString();
    } catch (Exception e) {
    }

    return StringPool.BLANK;
  }
  /**
   * Deletes the user group.
   *
   * @param userGroup the user group
   * @return the deleted user group
   */
  @Override
  @SystemEvent(action = SystemEventConstants.ACTION_SKIP, type = SystemEventConstants.TYPE_DELETE)
  public UserGroup deleteUserGroup(UserGroup userGroup) throws PortalException {

    if (!CompanyThreadLocal.isDeleteInProcess()) {
      int count =
          userLocalService.getUserGroupUsersCount(
              userGroup.getUserGroupId(), WorkflowConstants.STATUS_APPROVED);

      if (count > 0) {
        throw new RequiredUserGroupException();
      }
    }

    // Expando

    expandoRowLocalService.deleteRows(userGroup.getUserGroupId());

    // Group

    Group group = userGroup.getGroup();

    groupLocalService.deleteGroup(group);

    // User group roles

    userGroupGroupRoleLocalService.deleteUserGroupGroupRolesByUserGroupId(
        userGroup.getUserGroupId());

    // Resources

    resourceLocalService.deleteResource(
        userGroup.getCompanyId(),
        UserGroup.class.getName(),
        ResourceConstants.SCOPE_INDIVIDUAL,
        userGroup.getUserGroupId());

    // User group

    userGroupPersistence.remove(userGroup);

    // Permission cache

    PermissionCacheUtil.clearCache();

    return userGroup;
  }
  /**
   * Adds a user group.
   *
   * <p>This method handles the creation and bookkeeping of the user group, including its resources,
   * metadata, and internal data structures. It is not necessary to make subsequent calls to setup
   * default groups and resources for the user group.
   *
   * @param userId the primary key of the user
   * @param companyId the primary key of the user group's company
   * @param name the user group's name
   * @param description the user group's description
   * @param serviceContext the service context to be applied (optionally <code>null</code>). Can set
   *     expando bridge attributes for the user group.
   * @return the user group
   */
  @Override
  public UserGroup addUserGroup(
      long userId, long companyId, String name, String description, ServiceContext serviceContext)
      throws PortalException {

    // User group

    validate(0, companyId, name);

    User user = userPersistence.findByPrimaryKey(userId);

    long userGroupId = counterLocalService.increment();

    UserGroup userGroup = userGroupPersistence.create(userGroupId);

    if (serviceContext != null) {
      userGroup.setUuid(serviceContext.getUuid());
    }

    userGroup.setCompanyId(companyId);
    userGroup.setUserId(user.getUserId());
    userGroup.setUserName(user.getFullName());
    userGroup.setParentUserGroupId(UserGroupConstants.DEFAULT_PARENT_USER_GROUP_ID);
    userGroup.setName(name);
    userGroup.setDescription(description);
    userGroup.setAddedByLDAPImport(UserGroupImportTransactionThreadLocal.isOriginatesFromImport());
    userGroup.setExpandoBridgeAttributes(serviceContext);

    userGroupPersistence.update(userGroup);

    // Group

    groupLocalService.addGroup(
        userId,
        GroupConstants.DEFAULT_PARENT_GROUP_ID,
        UserGroup.class.getName(),
        userGroup.getUserGroupId(),
        GroupConstants.DEFAULT_LIVE_GROUP_ID,
        getLocalizationMap(String.valueOf(userGroupId)),
        null,
        0,
        true,
        GroupConstants.DEFAULT_MEMBERSHIP_RESTRICTION,
        null,
        false,
        true,
        null);

    // Resources

    resourceLocalService.addResources(
        companyId,
        0,
        userId,
        UserGroup.class.getName(),
        userGroup.getUserGroupId(),
        false,
        false,
        false);

    // Indexer

    Indexer<UserGroup> indexer = IndexerRegistryUtil.nullSafeGetIndexer(UserGroup.class);

    indexer.reindex(userGroup);

    return userGroup;
  }
 @Override
 public String getDisplayName(UserGroup userGroup) {
   return userGroup.getName();
 }