/**
   * Make sure the signed in user is allowed to POST the data they are trying to POST. The user
   * should only be trying to update their own student status.
   *
   * @param request
   * @param response
   * @return
   */
  private boolean authenticateStudentStatusPOST(
      HttpServletRequest request, HttpServletResponse response) {
    boolean result = false;

    // get the signed in user
    User user = ControllerUtil.getSignedInUser();

    // get the parameters from the request
    String runIdString = request.getParameter("runId");
    String periodIdString = request.getParameter("periodId");
    String workgroupIdString = request.getParameter("workgroupId");
    String status = request.getParameter("status");

    try {
      Long runId = Long.parseLong(runIdString);
      Long periodId = Long.parseLong(periodIdString);
      Long workgroupId = Long.parseLong(workgroupIdString);

      // make sure the user is in the run, in the period, and is in the workgroup
      if (isUserInRun(user, runId)
          && isUserInPeriod(user, runId, periodId)
          && isUserInWorkgroupId(user, workgroupId)
          && status != null) {
        result = true;
      }

    } catch (NumberFormatException e) {
      e.printStackTrace();
    }

    return result;
  }
  /**
   * Make sure the signed in user is allowed to POST the data they are trying to POST. The user
   * should only be trying to update their own student status.
   *
   * @param request
   * @param response
   * @return
   */
  private boolean authenticateRunStatusPOST(
      HttpServletRequest request, HttpServletResponse response) {
    boolean result = false;

    // get the signed in user
    User user = ControllerUtil.getSignedInUser();

    // get the parameters from the request
    String runIdString = request.getParameter("runId");
    String status = request.getParameter("status");

    try {
      // get the run id
      Long runId = Long.parseLong(runIdString);

      // check if the user is the owner of the run and the status is not null
      if (isUserOwnerOfRun(user, runId) && status != null) {
        result = true;
      }
    } catch (NumberFormatException e) {
      e.printStackTrace();
    }

    return result;
  }
  /**
   * @see
   *     org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected ModelAndView handleRequestInternal(
      HttpServletRequest request, HttpServletResponse response) throws Exception {
    // check if user is logged in
    if (ControllerUtil.getSignedInUser() == null) {
      response.sendRedirect("/webapp/login.html");
      return null;
    }
    boolean authorized = authorize(request);
    if (!authorized) {
      // if request is for posting unsaved data and the user is not the same user as the one that
      // should be posting it,
      // forward them to the homepage
      if (request.getRequestURI().equals("/webapp/bridge/postdata.html")) {
        User signedInUser = ControllerUtil.getSignedInUser();
        if (signedInUser.getUserDetails() instanceof TeacherUserDetails) {
          response.sendRedirect(
              "/webapp" + TelsAuthenticationProcessingFilter.TEACHER_DEFAULT_TARGET_PATH);
          return null;
        } else if (signedInUser.getUserDetails() instanceof StudentUserDetails) {
          response.sendRedirect(
              "/webapp" + TelsAuthenticationProcessingFilter.STUDENT_DEFAULT_TARGET_PATH);
          return null;
        } else {
          response.sendError(
              HttpServletResponse.SC_UNAUTHORIZED, "You are not authorized to access this page");
          return null;
        }
      } else {
        response.sendError(
            HttpServletResponse.SC_UNAUTHORIZED, "You are not authorized to access this page");
        return null;
      }
    }
    String method = request.getMethod();
    if (method.equals("GET")) {
      return handleGet(request, response);
    } else if (method.equals("POST")) {
      return handlePost(request, response);
    }

    // we only handle GET and POST requests at this point.
    return null;
  }
  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();
    }
  }
  /**
   * @see
   *     org.springframework.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected ModelAndView handleRequestInternal(
      HttpServletRequest request, HttpServletResponse response) throws Exception {

    String outResponse = "";
    User user = ControllerUtil.getSignedInUser();
    Set<User> owners = new TreeSet<User>();
    owners.add(user);

    Project project = projectService.getById(Long.parseLong(request.getParameter(PROJECTID)));

    CreateOtmlModuleParameters params = new CreateOtmlModuleParameters();
    params.setName(project.getCurnit().getSdsCurnit().getName());
    params.setUrl(RooloOtmlModuleDao.defaultOtrunkCurnitUrl);
    params.setRetrieveotmlurl(
        Util.getPortalUrl(request) + "/repository/retrieveotml.html?otmlModuleId=");
    byte[] otmlbytes = (byte[]) project.getCurnit().accept(new CurnitGetOtmlVisitor());
    if (otmlbytes != null) {
      params.setOtml(otmlbytes);
      Curnit copiedCurnit = curnitService.createCurnit(params);

      ProjectParameters projParams = new ProjectParameters();

      projParams.setCurnitId(copiedCurnit.getId());
      projParams.setJnlpId(project.getJnlp().getId());
      projParams.setOwners(owners);
      projParams.setProjectname(project.getName());
      projParams.setProjectType(project.getProjectType());

      projectService.createProject(projParams);

      outResponse =
          "Project "
              + project.getName()
              + " has been successfully "
              + "copied and can be found in My Customized Projects.";
    } else {
      outResponse = "This project is not of a type that can be copied.";
    }

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject(RESPONSE, outResponse);
    return modelAndView;
  }
  private ModelAndView handlePost(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);

    if (type == null) {
      // post student data
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/postdata.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("flag")
        || type.equals("inappropriateFlag")
        || type.equals("annotation")) {
      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")) {
      RequestDispatcher requestDispatcher =
          vlewrappercontext.getRequestDispatcher("/peerreview.html");
      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("chatLog")) {
      RequestDispatcher requestDispatcher = vlewrappercontext.getRequestDispatcher("/chatLog.html");
      requestDispatcher.forward(request, response);
    } else if (type.equals("studentStatus")) {
      handleStudentStatus(request, response);
    } else if (type.equals("runStatus")) {
      handleRunStatus(request, response);
    }
    return null;
  }
    public JSONObject run() {
      // get the username and password for the ejabberd account
      String username = workgroupId;
      String password = generateUniqueIdMD5(workgroupId, runId);

      // get the xmmp server base url e.g. http://wise4.berkeley.edu:5285
      String xmppServerBaseUrl = portalProperties.getProperty("xmppServerBaseUrl");

      // get the xmpp server host name e.g. wise4.berkeley.edu
      String xmppServerHostName = ControllerUtil.getHostNameFromUrl(xmppServerBaseUrl);

      // make the request to register the user in the ejabberd database
      String bodyData =
          "register \"" + username + "\" \"" + xmppServerHostName + "\" \"" + password + "\"";
      HttpPostRequest httpPostRequestData =
          new HttpPostRequest(
              REQUEST_HEADERS_CONTENT, EMPTY_STRING_MAP, bodyData, "/rest", HttpStatus.SC_OK);

      try {
        // try to create a user.  if user already exists, xmpp server will throw 500 internal error
        // otherwise, it will return 200 OK. in either case, we've successfully created a user on
        // xmpp.
        this.transport.post(httpPostRequestData);
      } catch (HttpStatusCodeException e) {
        // this might mean that the user already exists on the xmpp server
        // e.printStackTrace();
      }

      JSONObject xmppUserObject = new JSONObject();

      try {
        // populate the xmppUserObject fields
        xmppUserObject.put("xmppUsername", username);
        xmppUserObject.put("xmppPassword", password);
      } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      return xmppUserObject;
    }
  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.web.servlet.mvc.AbstractController#handleRequestInternal(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse)
   */
  @Override
  protected ModelAndView handleRequestInternal(
      HttpServletRequest request, HttpServletResponse response) throws Exception {

    ModelAndView modelAndView = new ModelAndView();
    User user = ControllerUtil.getSignedInUser();

    // get library projects
    Set<String> tagNames = new TreeSet<String>();
    tagNames.add("library");
    List<Project> libraryProjectsList = this.projectService.getProjectListByTagNames(tagNames);

    // get user's owned projects
    List<Project> ownedProjectsList = this.projectService.getProjectList(user);
    // for now, don't separate archived projects; TODO: re-implement if archiving is re-enabled
    // List<Project> currentOwnedProjectsList = new ArrayList<Project>();
    // List<Project> archivedOwnedProjectsList = new ArrayList<Project>();

    // get user's shared projects
    List<Project> sharedProjectsList = this.projectService.getSharedProjectList(user);
    sharedProjectsList.removeAll(ownedProjectsList);
    // for now, don't separate archived projects; TODO: re-implement if archiving is re-enabled
    // List<Project> currentSharedProjectsList = new ArrayList<Project>();
    // List<Project> archivedSharedProjectsList = new ArrayList<Project>();

    // a set to hold the list of project ids in user's library
    Set<Long> projectIds = new TreeSet<Long>();

    // set root project ids, remove duplicates
    List<Project> ownedRemove = new ArrayList<Project>();
    for (int i = 0; i < ownedProjectsList.size(); i++) {
      if (ownedProjectsList.get(i).getRootProjectId() == null) {
        Long rootId = this.projectService.identifyRootProjectId(ownedProjectsList.get(i));
        ownedProjectsList.get(i).setRootProjectId(rootId);
      }
      Long id = (Long) ownedProjectsList.get(i).getId();
      projectIds.add(id);

      // check if project is in WISE library
      for (Project libProject : libraryProjectsList) {
        if (ownedProjectsList.get(i).getId() == libProject.getId()) {
          ownedRemove.add(ownedProjectsList.get(i));
        }
      }
      // if (project.isCurrent()) {
      // currentOwnedProjectsList.add(project);
      // } else {
      // archivedOwnedProjectsList.add(project);
      // }
    }
    // if project is in WISE library, remove from owned projects list (avoid duplicates)
    for (int i = 0; i < ownedRemove.size(); i++) {
      ownedProjectsList.remove(ownedRemove.get(i));
    }

    List<Project> sharedRemove = new ArrayList<Project>();
    for (int a = 0; a < sharedProjectsList.size(); a++) {
      Long rootId = this.projectService.identifyRootProjectId(sharedProjectsList.get(a));
      sharedProjectsList.get(a).setRootProjectId(rootId);
      Long id = (Long) sharedProjectsList.get(a).getId();
      projectIds.add(id);

      // check if project is in WISE library
      for (Project libProject : libraryProjectsList) {
        if (sharedProjectsList.get(a).getId() == libProject.getId()) {
          sharedRemove.add(sharedProjectsList.get(a));
        }
      }
      // if (project.isCurrent()) {
      // currentSharedProjectsList.add(project);
      // } else {
      // archivedSharedProjectsList.add(project);
      // }
    }

    // if project is in WISE library, remove from shared projects list (avoid duplicates)
    for (int a = 0; a < sharedRemove.size(); a++) {
      sharedProjectsList.remove(sharedRemove.get(a));
    }

    for (int x = 0; x < libraryProjectsList.size(); x++) {
      Long rootId = this.projectService.identifyRootProjectId(libraryProjectsList.get(x));
      libraryProjectsList.get(x).setRootProjectId(rootId);
      Long id = (Long) libraryProjectsList.get(x).getId();
      projectIds.add(id);
    }

    /* sort the project lists */
    // this.projectService.sortProjectsByDateCreated(currentOwnedProjectsList);
    // this.projectService.sortProjectsByDateCreated(archivedOwnedProjectsList);

    // modelAndView.addObject("currentOwnedProjectsList", currentOwnedProjectsList);
    // modelAndView.addObject("archivedOwnedProjectsList", archivedOwnedProjectsList);

    // this.projectService.sortProjectsByDateCreated(currentSharedProjectsList);
    // this.projectService.sortProjectsByDateCreated(archivedSharedProjectsList);

    // modelAndView.addObject("currentSharedProjectsList", currentSharedProjectsList);
    // modelAndView.addObject("archivedSharedProjectsList", archivedSharedProjectsList);

    this.projectService.sortProjectsByDateCreated(ownedProjectsList);
    this.projectService.sortProjectsByDateCreated(sharedProjectsList);
    // this.projectService.sortProjectsByDateCreated(libraryProjectsList);

    // Map<Long, Integer> usageMap = new TreeMap<Long, Integer>();
    Map<Long, String> urlMap = new TreeMap<Long, String>();
    Map<Long, String> projectThumbMap =
        new TreeMap<Long, String>(); // maps projectId to url where its thumbnail can be found
    Map<Long, String> filenameMap = new TreeMap<Long, String>();

    // a map to contain projectId to project name
    Map<Long, String> projectNameMap = new TreeMap<Long, String>();

    // a map to contain projectId to escaped project name
    Map<Long, String> projectNameEscapedMap = new TreeMap<Long, String>();

    // a map to contain projectId to run date
    Map<Long, Date> projectRunDateMap = new TreeMap<Long, Date>();

    // a map to contain projectId to run date
    Map<Long, Long> projectRunIdMap = new TreeMap<Long, Long>();

    String curriculumBaseDir = this.portalProperties.getProperty("curriculum_base_dir");
    String curriculumBaseWWW = this.portalProperties.getProperty("curriculum_base_www");
    for (Project p : ownedProjectsList) {
      if (p.isCurrent()) {
        List<Run> runList = this.runService.getProjectRuns((Long) p.getId());
        if (!runList.isEmpty()) {
          // add project and date to the maps of project runs
          // since a project can now only be run once, just use the first run in the list
          projectRunDateMap.put((Long) p.getId(), runList.get(0).getStarttime());
          projectRunIdMap.put((Long) p.getId(), (Long) runList.get(0).getId());
        }

        String url = (String) p.getCurnit().accept(new CurnitGetCurnitUrlVisitor());

        // get the project name and put it into the map
        String projectName = p.getName();
        projectNameMap.put((Long) p.getId(), projectName);

        // replace ' with \' in the project name and put it into the map
        projectName = projectName.replaceAll("\\'", "\\\\'");
        projectNameEscapedMap.put((Long) p.getId(), projectName);

        if (url != null && url != "") {
          /*
           * add the project url to the map
           * e.g.
           * /253/wise4.project.json
           */
          urlMap.put((Long) p.getId(), url);

          int ndx = url.lastIndexOf("/");
          if (ndx != -1) {
            /*
             * add project thumb url to projectThumbMap. for now this is the same (/assets/project_thumb.png)
             * for all projects but this could be overwritten in the future
             * e.g.
             * /253/assets/projectThumb.png
             */
            projectThumbMap.put(
                (Long) p.getId(), curriculumBaseWWW + url.substring(0, ndx) + PROJECT_THUMB_PATH);

            /*
             * add the project file name to the map
             * e.g.
             * /wise4.project.json
             */
            filenameMap.put((Long) p.getId(), url.substring(ndx, url.length()));
          }
        }
        // usageMap.put((Long) p.getId(), this.runService.getProjectUsage((Long) p.getId()));
      }
    }

    for (Project p : sharedProjectsList) {
      if (p.isCurrent()) {
        List<Run> runList = this.runService.getProjectRuns((Long) p.getId());
        if (!runList.isEmpty()) {
          // add project and date to the maps of project runs
          // since a project can now only be run once, just use the first run in the list
          projectRunDateMap.put((Long) p.getId(), runList.get(0).getStarttime());
          projectRunIdMap.put((Long) p.getId(), (Long) runList.get(0).getId());
        }

        String url = (String) p.getCurnit().accept(new CurnitGetCurnitUrlVisitor());

        // get the project name and put it into the map
        String projectName = p.getName();
        projectNameMap.put((Long) p.getId(), projectName);

        // replace ' with \' in the project name and put it into the map
        projectName = projectName.replaceAll("\\'", "\\\\'");
        projectNameEscapedMap.put((Long) p.getId(), projectName);

        if (url != null && url != "") {
          /*
           * add the project url to the map
           * e.g.
           * /253/wise4.project.json
           */
          urlMap.put((Long) p.getId(), url);

          int ndx = url.lastIndexOf("/");
          if (ndx != -1) {
            /*
             * add project thumb url to projectThumbMap. for now this is the same (/assets/project_thumb.png)
             * for all projects but this could be overwritten in the future
             * e.g.
             * /253/assets/projectThumb.png
             */
            projectThumbMap.put(
                (Long) p.getId(), curriculumBaseWWW + url.substring(0, ndx) + PROJECT_THUMB_PATH);

            /*
             * add the project file name to the map
             * e.g.
             * /wise4.project.json
             */
            filenameMap.put((Long) p.getId(), url.substring(ndx, url.length()));
          }
        }
        // usageMap.put((Long) p.getId(), this.runService.getProjectUsage((Long) p.getId()));
      }
    }

    for (Project p : libraryProjectsList) {
      if (p.isCurrent()) {
        List<Run> runList = this.runService.getProjectRuns((Long) p.getId());
        if (!runList.isEmpty()) {
          // add project and date to the maps of project runs
          // since a project can now only be run once, just use the first run in the list
          projectRunDateMap.put((Long) p.getId(), runList.get(0).getStarttime());
          projectRunIdMap.put((Long) p.getId(), (Long) runList.get(0).getId());
        }

        String url = (String) p.getCurnit().accept(new CurnitGetCurnitUrlVisitor());

        // get the project name and put it into the map
        String projectName = p.getName();
        projectNameMap.put((Long) p.getId(), projectName);

        // replace ' with \' in the project name and put it into the map
        projectName = projectName.replaceAll("\\'", "\\\\'");
        projectNameEscapedMap.put((Long) p.getId(), projectName);

        if (url != null && url != "") {
          /*
           * add the project url to the map
           * e.g.
           * /253/wise4.project.json
           */
          urlMap.put((Long) p.getId(), url);

          int ndx = url.lastIndexOf("/");

          if (ndx != -1) {
            /*
             * add project thumb url to projectThumbMap. for now this is the same (/assets/project_thumb.png)
             * for all projects but this could be overwritten in the future
             * e.g.
             * /253/assets/projectThumb.png
             */
            String projectThumbPath =
                curriculumBaseWWW + url.substring(0, ndx) + PROJECT_THUMB_PATH;
            projectThumbMap.put((Long) p.getId(), projectThumbPath);

            /*
             * add the project file name to the map
             * e.g.
             * /wise4.project.json
             */
            filenameMap.put((Long) p.getId(), url.substring(ndx, url.length()));
          }
        }
        // usageMap.put((Long) p.getId(), this.runService.getProjectUsage((Long) p.getId()));
      }
    }

    // send in owned, shared, library, bookmarked projects, and list of project ids
    List<Project> bookmarkedProjectsList = this.projectService.getBookmarkerProjectList(user);
    modelAndView.addObject("bookmarkedProjectsList", bookmarkedProjectsList);
    modelAndView.addObject("ownedProjectsList", ownedProjectsList);
    modelAndView.addObject("sharedProjectsList", sharedProjectsList);
    modelAndView.addObject("libraryProjectsList", libraryProjectsList);
    modelAndView.addObject("projectIds", projectIds);
    modelAndView.addObject("sharedRemove", sharedRemove);
    modelAndView.addObject("ownedRemove", ownedRemove);

    // modelAndView.addObject("usageMap", usageMap);
    modelAndView.addObject("urlMap", urlMap);
    modelAndView.addObject("projectThumbMap", projectThumbMap);
    modelAndView.addObject("filenameMap", filenameMap);
    modelAndView.addObject("curriculumBaseDir", curriculumBaseDir);
    modelAndView.addObject("curriculumBaseWWW", curriculumBaseWWW);
    modelAndView.addObject("projectNameMap", projectNameMap);
    modelAndView.addObject("projectNameEscapedMap", projectNameEscapedMap);
    modelAndView.addObject("projectRunDateMap", projectRunDateMap);
    modelAndView.addObject("projectRunIdMap", projectRunIdMap);
    modelAndView.addObject("user", user);
    return modelAndView;
  }
  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;
  }