/**
   * Updates a {@link FeedbackResponse} based on it's {@code id}.<br>
   * If the giver/recipient field is changed, the {@link FeedbackResponse} is updated by recreating
   * the response<br>
   * in order to prevent an id clash if the previous email is reused later on.
   */
  public void updateFeedbackResponse(FeedbackResponseAttributes responseToUpdate)
      throws InvalidParametersException, EntityDoesNotExistException, EntityAlreadyExistsException {

    // Create a copy.
    FeedbackResponseAttributes newResponse = new FeedbackResponseAttributes(responseToUpdate);
    FeedbackResponseAttributes oldResponse = null;
    if (newResponse.getId() == null) {
      oldResponse =
          frDb.getFeedbackResponse(
              newResponse.feedbackQuestionId, newResponse.giverEmail, newResponse.recipientEmail);
    } else {
      oldResponse = frDb.getFeedbackResponse(newResponse.getId());
    }

    if (oldResponse == null) {
      throw new EntityDoesNotExistException(
          "Trying to update a feedback response that does not exist.");
    }

    // Copy values that cannot be changed to defensively avoid invalid
    // parameters.
    newResponse.courseId = oldResponse.courseId;
    newResponse.feedbackSessionName = oldResponse.feedbackSessionName;
    newResponse.feedbackQuestionId = oldResponse.feedbackQuestionId;
    newResponse.feedbackQuestionType = oldResponse.feedbackQuestionType;

    if (newResponse.responseMetaData == null) {
      newResponse.responseMetaData = oldResponse.responseMetaData;
    }
    if (newResponse.giverEmail == null) {
      newResponse.giverEmail = oldResponse.giverEmail;
    }
    if (newResponse.recipientEmail == null) {
      newResponse.recipientEmail = oldResponse.recipientEmail;
    }
    if (newResponse.giverSection == null) {
      newResponse.giverSection = oldResponse.giverSection;
    }
    if (newResponse.recipientSection == null) {
      newResponse.recipientSection = oldResponse.recipientSection;
    }

    if (!newResponse.recipientEmail.equals(oldResponse.recipientEmail)
        || !newResponse.giverEmail.equals(oldResponse.giverEmail)) {
      // Recreate response to prevent possible future id conflict.
      try {
        newResponse.setId(null);
        frDb.createEntity(newResponse);
        frDb.deleteEntity(oldResponse);
      } catch (EntityAlreadyExistsException e) {
        log.warning("Trying to update an existing response to one that already exists.");
        throw new EntityAlreadyExistsException(
            e.getMessage()
                + Const.EOL
                + "Trying to update recipient for response to one that already exists for this giver.");
      }
    } else {
      frDb.updateFeedbackResponse(newResponse);
    }
  }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForQuestionInSection(
     String feedbackQuestionId, String section) {
   if (section == null) {
     return getFeedbackResponsesForQuestion(feedbackQuestionId);
   }
   return frDb.getFeedbackResponsesForQuestionInSection(feedbackQuestionId, section);
 }
  public boolean updateFeedbackResponseForChangingTeam(
      StudentEnrollDetails enrollment, FeedbackResponseAttributes response) {

    FeedbackQuestionAttributes question = fqLogic.getFeedbackQuestion(response.feedbackQuestionId);

    boolean isGiverSameForResponseAndEnrollment = response.giverEmail.equals(enrollment.email);
    boolean isReceiverSameForResponseAndEnrollment =
        response.recipientEmail.equals(enrollment.email);

    boolean shouldDeleteByChangeOfGiver =
        (isGiverSameForResponseAndEnrollment
            && (question.giverType == FeedbackParticipantType.TEAMS
                || question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS));
    boolean shouldDeleteByChangeOfRecipient =
        (isReceiverSameForResponseAndEnrollment
            && question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS);

    boolean shouldDeleteResponse = shouldDeleteByChangeOfGiver || shouldDeleteByChangeOfRecipient;

    if (shouldDeleteResponse) {
      frDb.deleteEntity(response);
    }

    return shouldDeleteResponse;
  }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForSessionToSection(
     String feedbackSessionName, String courseId, String section) {
   if (section == null) {
     return getFeedbackResponsesForSession(feedbackSessionName, courseId);
   } else {
     return frDb.getFeedbackResponsesForSessionToSection(feedbackSessionName, courseId, section);
   }
 }
  public void createFeedbackResponse(FeedbackResponseAttributes fra)
      throws InvalidParametersException {
    try {
      frDb.createEntity(fra);
    } catch (Exception EntityAlreadyExistsException) {
      try {
        FeedbackResponseAttributes existingFeedback = new FeedbackResponseAttributes();

        existingFeedback =
            frDb.getFeedbackResponse(fra.feedbackQuestionId, fra.giverEmail, fra.recipientEmail);
        fra.setId(existingFeedback.getId());

        frDb.updateFeedbackResponse(fra);
      } catch (Exception EntityDoesNotExistException) {
        Assumption.fail();
      }
    }
  }
 /** Get existing feedback responses from student or his team for the given question. */
 public List<FeedbackResponseAttributes> getFeedbackResponsesFromStudentOrTeamForQuestion(
     FeedbackQuestionAttributes question, StudentAttributes student) {
   if (question.giverType == FeedbackParticipantType.TEAMS) {
     return getFeedbackResponsesFromTeamForQuestion(
         question.getId(), question.courseId, student.team);
   } else {
     return frDb.getFeedbackResponsesFromGiverForQuestion(question.getId(), student.email);
   }
 }
  public List<FeedbackResponseAttributes> getFeedbackResponsesFromGiverForQuestionInSection(
      String feedbackQuestionId, String userEmail, String section) {

    if (section == null) {
      return getFeedbackResponsesFromGiverForQuestion(feedbackQuestionId, userEmail);
    }
    return frDb.getFeedbackResponsesFromGiverForQuestionInSection(
        feedbackQuestionId, userEmail, section);
  }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForSessionToSectionWithinRange(
     String feedbackSessionName, String courseId, String section, long range) {
   if (section == null) {
     return getFeedbackResponsesForSessionWithinRange(feedbackSessionName, courseId, range);
   } else {
     return frDb.getFeedbackResponsesForSessionToSectionWithinRange(
         feedbackSessionName, courseId, section, range);
   }
 }
  private List<FeedbackResponseAttributes> getFeedbackResponsesFromTeamForQuestion(
      String feedbackQuestionId, String courseId, String teamName) {

    List<FeedbackResponseAttributes> responses = new ArrayList<FeedbackResponseAttributes>();
    List<StudentAttributes> studentsInTeam = studentsLogic.getStudentsForTeam(teamName, courseId);

    for (StudentAttributes student : studentsInTeam) {
      responses.addAll(
          frDb.getFeedbackResponsesFromGiverForQuestion(feedbackQuestionId, student.email));
    }

    return responses;
  }
  public void updateFeedbackResponsesForChangingSection(
      String courseId, String userEmail, String oldSection, String newSection)
      throws EntityDoesNotExistException, InvalidParametersException {

    List<FeedbackResponseAttributes> responsesFromUser =
        getFeedbackResponsesFromGiverForCourse(courseId, userEmail);

    for (FeedbackResponseAttributes response : responsesFromUser) {
      response.giverSection = newSection;
      frDb.updateFeedbackResponse(response);
      frcLogic.updateFeedbackResponseCommentsForResponse(response.getId());
    }

    List<FeedbackResponseAttributes> responsesToUser =
        getFeedbackResponsesForReceiverForCourse(courseId, userEmail);

    for (FeedbackResponseAttributes response : responsesToUser) {
      response.recipientSection = newSection;
      frDb.updateFeedbackResponse(response);
      frcLogic.updateFeedbackResponseCommentsForResponse(response.getId());
    }
  }
  /**
   * Updates responses for a student when his team changes. This is done by deleting responses that
   * are no longer relevant to him in his new team.
   */
  public void updateFeedbackResponsesForChangingTeam(
      String courseId, String userEmail, String oldTeam, String newTeam)
      throws EntityDoesNotExistException {

    FeedbackQuestionAttributes question;

    List<FeedbackResponseAttributes> responsesFromUser =
        getFeedbackResponsesFromGiverForCourse(courseId, userEmail);

    for (FeedbackResponseAttributes response : responsesFromUser) {
      question = fqLogic.getFeedbackQuestion(response.feedbackQuestionId);
      if (question.giverType == FeedbackParticipantType.TEAMS
          || question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS
          || question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF) {
        frDb.deleteEntity(response);
      }
    }

    List<FeedbackResponseAttributes> responsesToUser =
        getFeedbackResponsesForReceiverForCourse(courseId, userEmail);

    for (FeedbackResponseAttributes response : responsesToUser) {
      question = fqLogic.getFeedbackQuestion(response.feedbackQuestionId);
      if (question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS
          || question.recipientType == FeedbackParticipantType.OWN_TEAM_MEMBERS_INCLUDING_SELF) {
        frDb.deleteEntity(response);
      }
    }

    if (studentsLogic.getStudentsForTeam(oldTeam, courseId).isEmpty()) {
      List<FeedbackResponseAttributes> responsesToTeam =
          getFeedbackResponsesForReceiverForCourse(courseId, oldTeam);
      for (FeedbackResponseAttributes response : responsesToTeam) {
        frDb.deleteEntity(response);
      }
    }
  }
  public void updateFeedbackResponseForChangingSection(
      StudentEnrollDetails enrollment, FeedbackResponseAttributes response)
      throws InvalidParametersException, EntityDoesNotExistException {

    FeedbackResponse feedbackResponse = frDb.getFeedbackResponseEntityOptimized(response);
    boolean isGiverSameForResponseAndEnrollment =
        feedbackResponse.getGiverEmail().equals(enrollment.email);
    boolean isReceiverSameForResponseAndEnrollment =
        feedbackResponse.getRecipientEmail().equals(enrollment.email);

    if (isGiverSameForResponseAndEnrollment) {
      feedbackResponse.setGiverSection(enrollment.newSection);
    }

    if (isReceiverSameForResponseAndEnrollment) {
      feedbackResponse.setRecipientSection(enrollment.newSection);
    }

    frDb.commitOutstandingChanges();

    if (isGiverSameForResponseAndEnrollment || isReceiverSameForResponseAndEnrollment) {
      frcLogic.updateFeedbackResponseCommentsForResponse(response.getId());
    }
  }
  private List<FeedbackResponseAttributes> getFeedbackResponsesForTeamMembersOfStudent(
      String feedbackQuestionId, StudentAttributes student) {

    List<StudentAttributes> studentsInTeam =
        studentsLogic.getStudentsForTeam(student.team, student.course);

    List<FeedbackResponseAttributes> teamResponses = new ArrayList<FeedbackResponseAttributes>();

    for (StudentAttributes studentInTeam : studentsInTeam) {
      if (studentInTeam.email.equals(student.email)) {
        continue;
      }
      List<FeedbackResponseAttributes> responses =
          frDb.getFeedbackResponsesForReceiverForQuestion(feedbackQuestionId, studentInTeam.email);
      teamResponses.addAll(responses);
    }

    return teamResponses;
  }
 public FeedbackResponseAttributes getFeedbackResponse(
     String feedbackQuestionId, String giverEmail, String recipient) {
   // TODO: check what is this line doing here!!!
   log.warning(feedbackQuestionId);
   return frDb.getFeedbackResponse(feedbackQuestionId, giverEmail, recipient);
 }
 public FeedbackResponseAttributes getFeedbackResponse(String feedbackResponseId) {
   return frDb.getFeedbackResponse(feedbackResponseId);
 }
 public void deleteFeedbackResponseAndCascade(FeedbackResponseAttributes responseToDelete) {
   frcLogic.deleteFeedbackResponseCommentsForResponse(responseToDelete.getId());
   frDb.deleteEntity(responseToDelete);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForQuestionWithinRange(
     String feedbackQuestionId, long range) {
   return frDb.getFeedbackResponsesForQuestionWithinRange(feedbackQuestionId, range);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesFromGiverForCourse(
     String courseId, String userEmail) {
   return frDb.getFeedbackResponsesFromGiverForCourse(courseId, userEmail);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForSession(
     String feedbackSessionName, String courseId) {
   return frDb.getFeedbackResponsesForSession(feedbackSessionName, courseId);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForQuestion(
     String feedbackQuestionId) {
   return frDb.getFeedbackResponsesForQuestion(feedbackQuestionId);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesForSessionWithinRange(
     String feedbackSessionName, String courseId, long range) {
   return frDb.getFeedbackResponsesForSessionWithinRange(feedbackSessionName, courseId, range);
 }
 public List<FeedbackResponseAttributes> getFeedbackResponsesFromGiverForQuestion(
     String feedbackQuestionId, String userEmail) {
   return frDb.getFeedbackResponsesFromGiverForQuestion(feedbackQuestionId, userEmail);
 }