protected synchronized RedirectView handleSaveAndContinue(ProjectWrapper pw) throws Exception {
   Project p = pw.getProject();
   Integer pidOld = p.getId();
   Integer pid = pidOld;
   ProjectWrapper pwNew = this.tempProjectManager.get(pidOld);
   pwNew.setProject(p);
   if (this.isProjectValid(pwNew)) {
     pwNew.setErrorMessage("");
     if (pidOld < 0) {
       String projectCode = this.projectDao.getNextProjectCode(p.getHostInstitution());
       pw.getProject().setProjectCode(projectCode);
       pid = this.projectDao.createProjectWrapper(pwNew);
       pwNew.getProject().setId(pid);
       this.tempProjectManager.register(pwNew);
       this.tempProjectManager.unregister(pidOld);
     } else {
       this.tempProjectManager.update(pidOld, pwNew);
       this.projectDao.updateProjectWrapper(pidOld, pwNew);
     }
   } else {
     // save error message
     this.tempProjectManager.update(pid, pwNew);
   }
   return new RedirectView("editproject?id=" + pid);
 }
 protected synchronized RedirectView handleSaveAndFinish(ProjectWrapper pw) throws Exception {
   Integer pid = pw.getProject().getId();
   if (this.isProjectValid(pw)) {
     Project p = pw.getProject();
     pw = this.tempProjectManager.get(pid);
     pw.setProject(p);
     if (pid < 0) {
       String projectCode = this.projectDao.getNextProjectCode(p.getHostInstitution());
       pw.getProject().setProjectCode(projectCode);
       pid = this.projectDao.createProjectWrapper(pw);
     } else {
       this.projectDao.updateProjectWrapper(pid, pw);
     }
     this.tempProjectManager.unregister(pid);
     return new RedirectView("viewproject?id=" + pid);
   } else {
     this.tempProjectManager.update(pid, pw);
     return new RedirectView("editproject?id=" + pid);
   }
 }
 // See a filterable list of all projects
 @RequestMapping(value = "viewprojects", method = RequestMethod.GET)
 public ModelAndView viewprojects(String query) throws Exception {
   ModelAndView mav = new ModelAndView();
   List<Project> ps = projectDao.getProjects();
   List<Project> filtered = new LinkedList<Project>();
   String q = null;
   if (query != null && !query.equals("")) q = query.toLowerCase();
   // mark projects as due if a review or follow-up is due
   Date now = new Date();
   DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
   for (Project p : ps) {
     String nextFollowUpDate = p.getNextFollowUpDate().trim();
     String nextReviewDate = p.getNextReviewDate().trim();
     if (!nextFollowUpDate.equals("") && now.after(df.parse(p.getNextFollowUpDate()))) {
       p.setNextFollowUpDate(p.getNextFollowUpDate() + " (due)");
     }
     if (!nextReviewDate.equals("") && now.after(df.parse(p.getNextReviewDate()))) {
       p.setNextReviewDate(p.getNextReviewDate() + " (due)");
     }
     if (q != null) {
       if (p.getName().toLowerCase().contains(q)
           || p.getDescription().toLowerCase().contains(q)
           || p.getHostInstitution().toLowerCase().contains(q)
           || p.getNotes().toLowerCase().contains(q)
           || p.getProjectCode().toLowerCase().contains(q)
           || p.getProjectTypeName().toLowerCase().contains(q)
           || p.getRequirements().toLowerCase().contains(q)
           || p.getTodo() != null && p.getTodo().toLowerCase().contains(q)) filtered.add(p);
     }
   }
   if (q == null) {
     mav.addObject("projects", ps);
   } else {
     mav.addObject("projects", filtered);
     mav.addObject("query", q);
   }
   return mav;
 }