/**
   * Check if the user is in the period
   *
   * @param user the user
   * @param runId the run id
   * @param periodId the period id
   * @return whether the user is in the period
   */
  private boolean isUserInPeriod(User user, Long runId, Long periodId) {
    boolean result = false;

    if (user != null && runId != null && periodId != null) {
      try {
        // get the run
        Run run = runService.retrieveById(runId);

        // get the period the student is in for the run
        Group periodOfStudent = run.getPeriodOfStudent(user);

        if (periodOfStudent != null) {
          // get the period id
          Long tempPeriodId = periodOfStudent.getId();

          // check if the period id matches the one we are searching for
          if (periodId.equals(tempPeriodId)) {
            // the period id matches so the user is in the period
            result = true;
          }
        }
      } catch (ObjectNotFoundException e) {
      }
    }

    return result;
  }
  /**
   * Check if the user is in the run
   *
   * @param user the user
   * @param runId the run id
   * @return whether the user is in the run
   */
  private boolean isUserInRun(User user, Long runId) {
    boolean result = false;

    if (user != null && runId != null) {
      // get the list of runs this user is in
      List<Run> runList = runService.getRunList(user);

      Iterator<Run> runListIterator = runList.iterator();

      // loop through all the runs this user is in
      while (runListIterator.hasNext()) {
        // get a run
        Run tempRun = runListIterator.next();

        if (tempRun != null) {
          // get the run id
          Long tempRunId = tempRun.getId();

          // check if the run id matches the one we are searching for
          if (runId.equals(tempRunId)) {
            // the run id matches so the user is in the run
            result = true;
            break;
          }
        }
      }
    }

    return result;
  }
  /**
   * Check if a user is the owner or shared owner of a run
   *
   * @param user the signed in user
   * @param runId the run id
   * @return whether the user is an owner of the run
   */
  private boolean isUserOwnerOfRun(User user, Long runId) {
    boolean result = false;

    if (user != null && runId != null) {
      try {
        // get the run
        Run run = runService.retrieveById(runId);

        if (run != null) {
          // get the owners and shared owners
          Set<User> owners = run.getOwners();
          Set<User> sharedowners = run.getSharedowners();

          if (owners.contains(user) || sharedowners.contains(user)) {
            // the user is the owner or a shared owner
            result = true;
          }
        }
      } catch (ObjectNotFoundException e) {
        e.printStackTrace();
      }
    }

    return result;
  }
  private void handleStudentAssetManager(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ServletContext servletContext2 = this.getServletContext();
    ServletContext vlewrappercontext = servletContext2.getContext("/vlewrapper");
    User user = ControllerUtil.getSignedInUser();
    String studentuploads_base_dir = portalProperties.getProperty("studentuploads_base_dir");

    try {
      // get the run
      String runId = request.getParameter("runId");
      Run run = runService.retrieveById(new Long(runId));

      // get the project id
      Project project = run.getProject();
      Serializable projectId = project.getId();

      // set the project id into the request so the vlewrapper controller has access to it
      request.setAttribute("projectId", projectId + "");

      // get the workgroup id
      List<Workgroup> workgroupListByOfferingAndUser =
          workgroupService.getWorkgroupListByOfferingAndUser(run, user);
      Workgroup workgroup = workgroupListByOfferingAndUser.get(0);
      Long workgroupId = workgroup.getId();

      // set the workgroup id into the request so the vlewrapper controller has access to it
      request.setAttribute(
          "dirName",
          run.getId()
              + "/"
              + workgroupId
              + "/unreferenced"); // looks like /studentuploads/[runId]/[workgroupId]/unreferenced
      String commandParamter = request.getParameter("command");
      if (commandParamter != null && "studentAssetCopyForReference".equals(commandParamter)) {
        request.setAttribute(
            "referencedDirName",
            run.getId()
                + "/"
                + workgroupId
                + "/referenced"); // if we're copying student asset for reference, also pass along
                                  // the referenced dir. looks like
                                  // /studentuploads/[runId]/[workgroupId]/referenced
      }
      if (studentuploads_base_dir != null) {
        request.setAttribute("studentuploads_base_dir", studentuploads_base_dir);
      }
      // forward the request to the vlewrapper controller
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/vle/studentassetmanager.html");
      requestDispatcher.forward(request, response);
    } catch (NumberFormatException e) {
      e.printStackTrace();
    } catch (ObjectNotFoundException e) {
      e.printStackTrace();
    }
  }
  private void handleViewStudentAssets(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ServletContext servletContext2 = this.getServletContext();
    ServletContext vlewrappercontext = servletContext2.getContext("/vlewrapper");
    User user = ControllerUtil.getSignedInUser();
    String studentuploads_base_dir = portalProperties.getProperty("studentuploads_base_dir");

    try {
      // get the run
      String runId = request.getParameter("runId");
      Run run = runService.retrieveById(new Long(runId));

      // get the project id
      Project project = run.getProject();
      Serializable projectId = project.getId();

      // set the project id into the request so the vlewrapper controller has access to it
      request.setAttribute("projectId", projectId + "");

      // set the workgroup id into the request so the vlewrapper controller has access to it
      if (studentuploads_base_dir != null) {
        request.setAttribute("studentuploads_base_dir", studentuploads_base_dir);
      }

      // workgroups is a ":" separated string of workgroups
      String workgroups = request.getParameter("workgroups");

      request.setAttribute("dirName", workgroups);

      // forward the request to the vlewrapper controller
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/vle/studentassetmanager.html");
      requestDispatcher.forward(request, response);
    } catch (NumberFormatException e) {
      e.printStackTrace();
    } catch (ObjectNotFoundException e) {
      e.printStackTrace();
    }
  }
  /**
   * @see org.springframework.validation.Validator#validate(java.lang.Object,
   *     org.springframework.validation.Errors)
   */
  public void validate(Object paramsIn, Errors errors) {
    FindProjectParameters param = (FindProjectParameters) paramsIn;

    /* there should be exactly on param field with data, reject
     * if less or more than one has data */
    int numWithData = 0;

    /* check and validate the project Id field */
    if (param.getProjectId() != null && !param.getProjectId().equals("")) {
      numWithData += 1;

      /* make sure project id is numeric */
      if (!StringUtils.isNumeric(param.getProjectId())) {
        errors.reject("error.projectId-not-numeric", "Project ID must be numeric.");
        return;
      }

      /* make sure that a project with the id exists */
      try {
        Project project = projectService.getById(Long.parseLong(param.getProjectId()));
        if (project == null) {
          errors.reject("error.projectId-not-found", "Project ID not found.");
          return;
        }
      } catch (Exception e) {
        errors.reject("error.projectId-not-found", "Project ID not found.");
        return;
      }
    }

    /* check and validate the userName field */
    if (param.getUserName() != null && !param.getUserName().equals("")) {
      numWithData += 1;

      /* make sure that a user with that name exists */
      if (userService.retrieveUserByUsername(param.getUserName()) == null) {
        errors.rejectValue("userName", "error.teacher-not-found");
      }
    }

    /* check and validate the runId field */
    if (param.getRunId() != null && !param.getRunId().equals("")) {
      numWithData += 1;

      /* make sure run id is numeric */
      if (!StringUtils.isNumeric(param.getRunId())) {
        errors.reject("error.runId-not-numeric", "Run ID must be numeric.");
        return;
      }

      /* make sure that a run with the given id exists */
      try {
        Run run = runService.retrieveById(Long.parseLong(param.getRunId()));
        if (run == null) {
          errors.reject("error.runId-not-found", "Run ID not found.");
          return;
        }
      } catch (ObjectNotFoundException e) {
        errors.reject("error.runId-not-found", "Run ID not found.");
        return;
      }
    }

    /* ensure that exactly one field was specified */
    if (numWithData != 1) {
      errors.reject("error.invalid-parameters", "Parameters passed to controller are invalid.");
    }
  }
  private void handleIdeaBasket(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    ServletContext servletContext2 = this.getServletContext();
    ServletContext vlewrappercontext = servletContext2.getContext("/vlewrapper");
    User signedInUser = ControllerUtil.getSignedInUser();
    String action = request.getParameter("action");

    try {
      // get the run
      String runId = request.getParameter("runId");
      Run run = runService.retrieveById(new Long(runId));

      // get the project id
      Project project = run.getProject();
      Serializable projectId = project.getId();

      // set the project id into the request so the vlewrapper controller has access to it
      request.setAttribute("projectId", projectId + "");

      // get the authorities for the signed in user
      MutableUserDetails signedInUserDetails = signedInUser.getUserDetails();
      Collection<? extends GrantedAuthority> authorities = signedInUserDetails.getAuthorities();

      boolean isAdmin = false;
      boolean isTeacher = false;
      boolean isStudent = false;

      // this value will determine whether the user can modify anything they want in the public idea
      // basket
      boolean isPrivileged = false;

      for (GrantedAuthority authority : authorities) {
        if (authority.getAuthority().equals(UserDetailsService.ADMIN_ROLE)) {
          // user is an admin or teacher
          isAdmin = true;
          isPrivileged = true;
        } else if (authority.getAuthority().equals(UserDetailsService.TEACHER_ROLE)) {
          // user is an admin or teacher
          isTeacher = true;
          isPrivileged = true;
        }
      }

      if (!isTeacher) {
        isStudent = true;
      }

      request.setAttribute("isPrivileged", isPrivileged);

      if (isAdmin) {
        // user is an admin so we do not need to retrieve the workgroup id
      } else if (isTeacher) {
        // user is a teacher so we will retrieve their workgroup id for the run

        // get the workgroup id
        List<Workgroup> workgroupListByOfferingAndUser =
            workgroupService.getWorkgroupListByOfferingAndUser(run, signedInUser);
        // add nullpointer check
        Workgroup workgroup = workgroupListByOfferingAndUser.get(0);
        Long signedInWorkgroupId = workgroup.getId();

        // set the workgroup id into the request so the vlewrapper controller has access to it
        request.setAttribute("signedInWorkgroupId", signedInWorkgroupId + "");
      } else if (isStudent) {
        /*
         * the user is a student so we will make sure the run id
         * matches the run they are currently working on and then
         * retrieve their workgroup id for the run
         */

        HashMap<String, Run> studentsToRuns =
            (HashMap<String, Run>)
                request.getSession().getServletContext().getAttribute("studentsToRuns");

        String sessionId = request.getSession().getId();

        if (studentsToRuns != null && studentsToRuns.containsKey(sessionId)) {
          Run sessionRun = studentsToRuns.get(sessionId);
          Long sessionRunId = sessionRun.getId();

          if (sessionRunId.equals(new Long(runId))) {
            // get the workgroup id
            List<Workgroup> workgroupListByOfferingAndUser =
                workgroupService.getWorkgroupListByOfferingAndUser(run, signedInUser);
            // add nullpointer check
            Workgroup workgroup = workgroupListByOfferingAndUser.get(0);
            Long signedInWorkgroupId = workgroup.getId();

            // set the workgroup id into the request so the vlewrapper controller has access to it
            request.setAttribute("signedInWorkgroupId", signedInWorkgroupId + "");
          } else {
            // run id does not match the run that the student is logged in to
            response.sendError(
                HttpServletResponse.SC_UNAUTHORIZED,
                "Run id does not match run that student is logged in to");
            return;
          }
        } else {
          // session id was not found which means the session probably timed out
          response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Session no longer valid");
          return;
        }
      }

      // forward the request to the vlewrapper controller
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/ideaBasket.html");
      requestDispatcher.forward(request, response);
    } catch (NumberFormatException e) {
      e.printStackTrace();
    } catch (ObjectNotFoundException e) {
      e.printStackTrace();
    }
  }
  private ModelAndView handleGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String type = request.getParameter("type");
    ServletContext servletContext2 = this.getServletContext();
    ServletContext vlewrappercontext = servletContext2.getContext("/vlewrapper");

    User user = ControllerUtil.getSignedInUser();
    CredentialManager.setRequestCredentials(request, user);

    // get the run id
    String runIdString = request.getParameter("runId");
    Long runId = null;

    if (runIdString != null) {
      runId = Long.parseLong(runIdString);
    }

    Run run = null;
    try {
      if (runId != null) {
        // get the run object
        run = runService.retrieveById(runId);
      }
    } catch (ObjectNotFoundException e1) {
      e1.printStackTrace();
    }

    if (type == null) {
      // get student data
      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/getdata.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("brainstorm")) {
      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/getdata.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("aggregate")) {
      setProjectPath(run, request); // set the project path into the request object
      if (Boolean.parseBoolean(request.getParameter("allStudents"))) {
        // request for all students work in run. lookup workgroups in run and construct
        // workgroupIdString
        String workgroupIdStr = "";
        try {
          Set<Workgroup> workgroups = runService.getWorkgroups(runId);
          for (Workgroup workgroup : workgroups) {
            workgroupIdStr += workgroup.getId() + ":";
          }
          request.setAttribute("userId", workgroupIdStr);
        } catch (ObjectNotFoundException e) {
        }
      }

      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/getdata.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("flag")
        || type.equals("inappropriateFlag")
        || type.equals("annotation")) { // get flags
      /*
       * set the user info JSONObjects into the request so the vlewrapper servlet
       * has access to the teacher and classmate info
       */
      setUserInfos(run, request);

      setCRaterAttributes(request);

      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/annotations.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("journal")) {
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/journaldata.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("peerreview")) {
      // get the period id
      String periodString = request.getParameter("periodId");
      Long period = null;
      if (periodString != null) {
        period = Long.parseLong(periodString);
      }

      try {
        /*
         * set the number of students in the class period for when we need
         * to calculate peer review opening
         */
        Set<Workgroup> classmateWorkgroups = runService.getWorkgroups(runId, period);
        request.setAttribute("numWorkgroups", classmateWorkgroups.size());
      } catch (ObjectNotFoundException e) {
        e.printStackTrace();
      }
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/peerreview.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("xlsexport") || type.equals("specialExport")) {
      // set the user info into the request object
      setUserInfos(run, request);

      // set the project path into the request object
      setProjectPath(run, request);

      // set the project meta data into the request object
      setProjectMetaData(run, request);

      String requestPath = "";

      if (type.equals("xlsexport")) {
        // get the path for regular exports
        requestPath = "/getxls.html";
      } else if (type.equals("specialExport")) {
        // get the path for special exports
        requestPath = "/getSpecialExport.html";
      }

      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher(requestPath);
      requestDispatcher.forward(request, response);
    } else if (type.equals("ideaBasket")) {
      handleIdeaBasket(request, response);
    } else if (type.equals("studentAssetManager")) {
      handleStudentAssetManager(request, response);
    } else if (type.equals("viewStudentAssets")) {
      handleViewStudentAssets(request, response);
    } else if (type.equals("xmppAuthenticate")) {
      // check if this portal is xmpp enabled first
      String isXMPPEnabled = portalProperties.getProperty("isXMPPEnabled");
      if (isXMPPEnabled != null && Boolean.valueOf(isXMPPEnabled)) {
        handleWISEXMPPAuthenticate(request, response);
      }
    } else if (type.equals("cRater")) {
      setCRaterAttributes(request);

      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/cRater.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("chatLog")) {
      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/chatLog.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("studentStatus")) {
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/studentStatus.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("runStatus")) {
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/runStatus.html");
      requestDispatcher.forward(request, response);
    }

    return null;
  }
  private boolean authorize(HttpServletRequest request) {
    String method = request.getMethod();
    User signedInUser = ControllerUtil.getSignedInUser();
    Collection<? extends GrantedAuthority> authorities =
        signedInUser.getUserDetails().getAuthorities();
    Long signedInUserId = null;
    for (GrantedAuthority authority : authorities) {
      if (authority.getAuthority().equals(UserDetailsService.ADMIN_ROLE)) {
        return true;
      } else if (authority.getAuthority().equals(UserDetailsService.TEACHER_ROLE)) {
        // the signed in user is a teacher

        String type = request.getParameter("type");
        if ("cRater".equals(type)) {
          // any teacher can make a cRater request
          return true;
        }

        Run run = null;
        try {
          // get the run object
          run = runService.retrieveById(new Long(request.getParameter("runId")));
        } catch (NumberFormatException e) {
          e.printStackTrace();
        } catch (ObjectNotFoundException e) {
          e.printStackTrace();
        }

        if (run == null) {
          // we could not find the run
          return false;
        } else if (this.runService.hasRunPermission(run, signedInUser, BasePermission.WRITE)) {
          // the teacher has write permission for the run so we will allow authorization
          return true;
        } else if (this.runService.hasRunPermission(run, signedInUser, BasePermission.READ)) {
          // the teacher only has read permission for the run

          if (method.equals("GET")) {
            // we will allow authorization for GET requests
            return true;
          } else if (method.equals("POST")) {
            // we will deny authorization for POST requests since the teacher only has READ
            // permissions
            return false;
          }
        }
      }
    }
    if (method.equals("GET")) {
      String workgroupIdStr = "";

      // only used for annotations
      String fromWorkgroupIdStr = "";

      String type = request.getParameter("type");

      String runIdString = request.getParameter("runId");
      Long runId = null;

      if (runIdString != null) {
        runId = Long.parseLong(runIdString);
      }

      String periodString = request.getParameter("periodId");
      Long period = null;
      if (periodString != null) {
        period = Long.parseLong(periodString);
      }

      if (runId != null) {
        try {
          // get the run
          Run offering = runService.retrieveById(runId);

          // get the workgroup for the signed in user
          List<Workgroup> workgroupListByOfferingAndUser =
              workgroupService.getWorkgroupListByOfferingAndUser(offering, signedInUser);

          // get the workgroup
          Workgroup workgroup = workgroupListByOfferingAndUser.get(0);

          // get the workgroup id
          signedInUserId = workgroup.getId();
        } catch (ObjectNotFoundException e1) {
          e1.printStackTrace();
        }
      }

      // whether this GET request can access other workgroup's data
      boolean canAccessOtherWorkgroups = false;

      if (type == null) {
        workgroupIdStr = request.getParameter("userId");
      } else if (type.equals("flag") || type.equals("inappropriateFlag")) {
        workgroupIdStr = request.getParameter("userId");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("annotation")) {
        String annotationType = request.getParameter("annotationType");
        if ("cRater".equals(annotationType)) {
          // anyone can make a cRater annotation
          return true;
        }
        workgroupIdStr = request.getParameter("toWorkgroup");

        // get the fromWorkgroup id
        fromWorkgroupIdStr = request.getParameter("fromWorkgroup");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("brainstorm")) {
        workgroupIdStr = request.getParameter("userId");
        canAccessOtherWorkgroups = true;
      } else if (type.equals("aggregate")) {
        // student/teacher is trying to get other students' work so that it can be used to show
        // the aggregate view. nodeIds should be passed in.
        // Check that the nodeIds exist and that we can get the student data from them
        // in the VLE.
        if (request.getParameter("nodeIds") == null) {
          canAccessOtherWorkgroups = false;
        } else {
          if (request.getParameter("allStudents") != null
              && Boolean.valueOf(request.getParameter("allStudents"))) {
            return true;
          } else {
            workgroupIdStr = request.getParameter("userId");
            canAccessOtherWorkgroups = true;
          }
        }
      } else if (type.equals("journal")) {
        workgroupIdStr = request.getParameter("workgroupId");
      } else if (type.equals("peerreview")) {
        // return true for now until logic is implemented
        return true;
      } else if (type.equals("xlsexport") || type.equals("specialExport")) {
        // TODO: need to check user permissions
        return true;
      } else if (type.equals("ideaBasket")) {
        return true;
      } else if (type.equals("studentAssetManager")) {
        return true;
      } else if (type.equals("xmppAuthenticate")) {
        return true;
      } else if (type.equals("cRater")) {
        // allow students to make cRater scoring requests
        String cRaterRequestType = request.getParameter("cRaterRequestType");
        if ("scoring".equals(cRaterRequestType)) {
          return true;
        }
      } else if (type.equals("runStatus")) {
        // check if the user is the owner of the run or in the run
        if (isUserOwnerOfRun(signedInUser, runId) || isUserInRun(signedInUser, runId)) {
          return true;
        }
      } else {
        // this should never happen
      }

      if (workgroupIdStr == null || workgroupIdStr.equals("")) {
        return false;
      }
      // split up all the workgroup ids
      String[] workgroupIds = workgroupIdStr.split(":");

      // check if this GET request can access other workgroups
      if (canAccessOtherWorkgroups) {
        // this GET request is allowed to access other workgroup work
        try {
          if (fromWorkgroupIdStr != null
              && !fromWorkgroupIdStr.equals("")
              && fromWorkgroupIdStr.equals(signedInUserId)) {
            /*
             * the signed in user id is the same as the from workgroup id so
             * we will allow it. this basically means the current user is
             * requesting the annotations that he/she wrote.
             */
            return true;
          } else {
            // obtain all the workgroups of the classmates of the current user
            Set<Workgroup> classmateWorkgroups = runService.getWorkgroups(runId, period);

            /*
             * see if the workgroupIds the user is trying to access is
             * in the above set of classmate workgroups, if all the
             * workgroupIds beingaccessed are allowed, it will return
             * true and allow it, otherwise it will return false and
             * deny access
             */
            return elementsInCollection(workgroupIds, classmateWorkgroups);
          }
        } catch (ObjectNotFoundException e) {
          e.printStackTrace();
        }
      } else {
        /*
         * this GET request is not allowed to access other workgroup work
         * it can only access the workgroup the current user is in
         */

        // obtain all the workgroups that the current user is in
        List<Workgroup> workgroupsForUser = workgroupService.getWorkgroupsForUser(signedInUser);

        /*
         * see if the workgroupIds the user is trying to access is in
         * the above list of workgroups, if all the workgroupIds being
         * accessed are allowed, it will return true and allow it,
         * otherwise it will return false and deny access
         */
        return elementsInCollection(workgroupIds, workgroupsForUser);
      }

      return false;
    } else if (method.equals("POST")) {
      return true;
    }
    // other request methods are not authorized at this point
    return false;
  }