/*
   * Update the roles for the user.
   * @param editRoles the new set of roles for the user
   * @param permissionsHelper the PermissionsHelper
   */
  private void updateRoles(
      PermissionsUserEditRoles editRoles, PermissionsHelperBase permissionsHelper) {

    /*
     * Clear the current roles before setting the new ones
     */
    Role rolePI = null;
    Role roleCOI = null;
    UserState userState = permissionsHelper.getUserState(editRoles.getUserName());
    List<RoleState> statesList = userState.getRoleStates();
    for (RoleState roleState : statesList) {
      if (Constants.CO_INVESTIGATOR_ROLE.equalsIgnoreCase(roleState.getRole().getName())
          && roleState.isAssigned()) {
        roleCOI = roleState.getRole();
      }
      if (Constants.PRINCIPAL_INVESTIGATOR_ROLE.equalsIgnoreCase(roleState.getRole().getName())
          && roleState.isAssigned()) {
        rolePI = roleState.getRole();
      }
    }
    userState.clearAssignments();

    /*
     * Set the new roles.
     */

    List<PermissionsRoleState> roleStates = editRoles.getRoleStates();
    PermissionsRoleState permissionsRoleState = null;

    if (roleCOI != null) {
      permissionsRoleState = new PermissionsRoleState(roleCOI);
      permissionsRoleState.setState(true);
      if (permissionsRoleState != null || permissionsRoleState.getState()) {
        roleStates.add(permissionsRoleState);
      }
    }

    if (rolePI != null) {
      permissionsRoleState = new PermissionsRoleState(rolePI);
      permissionsRoleState.setState(true);
      if (permissionsRoleState != null || permissionsRoleState.getState()) {
        roleStates.add(permissionsRoleState);
      }
    }

    for (PermissionsRoleState roleState : roleStates) {
      if (roleState.getState()) {
        userState.setAssigned(roleState.getRole().getName(), true);
      }
    }

    // If the user isn't assigned to any of the normal roles, then he/she will
    // be assigned to the unassigned role.

    if (!userState.hasAnyRole() && permissionsHelper.getUnassignedRoleName() != null) {
      userState.setAssigned(permissionsHelper.getUnassignedRoleName(), true);
    }
  }
  @Override
  public ActionForward editRoles(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    PermissionsForm permissionsForm = (PermissionsForm) form;
    PermissionsHelperBase permissionsHelper = permissionsForm.getPermissionsHelper();

    int lineNum = getLineNum(request);
    User user = permissionsHelper.getUsers().get(lineNum);

    /*
     * Create an Edit Roles BO that will be used by the form for setting
     * the boolean flags for the roles.
     */
    PermissionsUserEditRoles editRoles = new PermissionsUserEditRoles();
    editRoles.setLineNum(lineNum);
    editRoles.setJavaScriptEnabled(isJavaScriptEnabled(request));
    editRoles.setUserName(user.getPerson().getUserName());
    editRoles.setPrinipalInvestigator(
        isPrincipalInvestigator(
            (ProtocolDocument) permissionsForm.getDocument(), user.getPerson().getPersonId()));

    List<PermissionsRoleState> roleStates = new ArrayList<PermissionsRoleState>();
    List<Role> roles = permissionsHelper.getNormalRoles();
    for (Role role : roles) {
      if (RoleConstants.VIEWER.equalsIgnoreCase(role.getDisplayName())
          || RoleConstants.AGGREGATOR.equalsIgnoreCase(role.getDisplayName())
          || role.getDisplayName().equalsIgnoreCase(MAINTAIN_IRB_QUESTIONNAIRE)
          || role.getDisplayName().equalsIgnoreCase(PROTOCOL_DELETER)) {
        PermissionsRoleState roleState = new PermissionsRoleState(role);
        roleStates.add(roleState);
      }
    }
    editRoles.setRoleStates(roleStates);

    /*
     * Initialize the Edit Roles BO to the roles that the user is currently assigned to.
     */
    List<Role> userRoles = user.getRoles();
    for (Role userRole : userRoles) {
      editRoles.setRoleState(userRole.getName(), Boolean.TRUE);
    }

    permissionsHelper.setUserEditRoles(editRoles);

    return mapping.findForward(Constants.MAPPING_PERMISSIONS_EDIT_ROLES_PAGE);
  }
  /**
   * Set the roles for a user for a given document. The setEditRoles() method works in conjunction
   * with the above editRoles() method. The editRoles() method causes the Edit Roles web page to be
   * displayed. The setEditRoles() is invoked when the user clicks on the save button. Note that the
   * Edit Roles BO created in editRoles() is retrieved in setEditRoles() to determine the user and
   * what the new roles should be.
   *
   * @param mapping the mapping associated with this action.
   * @param form the form.
   * @param request the HTTP request
   * @param response the HTTP response
   * @return the next web page to display
   * @throws Exception
   */
  @Override
  public ActionForward setEditRoles(
      ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception {

    ActionForward actionForward = null;

    PermissionsHelperBase permissionsHelper = ((PermissionsForm) form).getPermissionsHelper();
    PermissionsForm permissionsForm = (PermissionsForm) form;
    Document doc = permissionsForm.getDocument();

    // early exit if not authorized
    if (!permissionsHelper.canModifyPermissions()) {
      return protocolPermissionsAction.processAuthorizationViolation(
          SET_EDIT_ROLES_METHOD, mapping, form, request, response);
    }

    // The Edit Roles BO contains the username, javascriptEnabled, and the new set of
    // roles to set for the user in the document.

    PermissionsUserEditRoles editRoles = permissionsHelper.getEditRoles();

    // check any business rules
    boolean rulePassed =
        applyRules(new EditUserPermissionsRolesEvent(doc, permissionsHelper.getUsers(), editRoles));
    if (!rulePassed) {

      // If the user can't perform the save of the roles, then we will report the
      // error on the Edit Roles web page.  This allows the user to fix the error
      // and re-submit the save.

      actionForward = mapping.findForward(Constants.MAPPING_PERMISSIONS_EDIT_ROLES_PAGE);
    } else {
      updateRoles(editRoles, permissionsHelper);

      // If Javascript was enabled, we can simply cause the pop-up window to close.
      // If not, then we must return the user to the Permissions page.

      if (editRoles.getJavaScriptEnabled()) {
        actionForward = mapping.findForward(Constants.MAPPING_PERMISSIONS_CLOSE_EDIT_ROLES_PAGE);
      } else {
        actionForward = mapping.findForward(Constants.MAPPING_BASIC);
      }
    }

    return actionForward;
  }