src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java

changeset 99
a369fb1b3aa2
parent 97
602f75801644
child 100
7e3c61c340d3
--- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java	Sat Aug 22 18:34:36 2020 +0200
+++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java	Sun Aug 23 15:10:49 2020 +0200
@@ -39,14 +39,13 @@
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 import java.io.IOException;
 import java.sql.Date;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.NoSuchElementException;
-import java.util.Objects;
+import java.util.Optional;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -60,178 +59,43 @@
 
     private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class);
 
-    public static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project");
-    public static final String SESSION_ATTR_SELECTED_ISSUE = fqn(ProjectsModule.class, "selected_issue");
-    public static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version");
-
-    // TODO: try to get rid of this shit
-    private class SessionSelection {
-        final HttpSession session;
-        final HttpServletRequest req;
-        final DataAccessObjects dao;
-        Project project;
-        Version version;
-        Issue issue;
-
-        SessionSelection(HttpServletRequest req, DataAccessObjects dao) {
-            this.req = req;
-            this.dao = dao;
-            session = req.getSession();
-        }
-
-        void newProject() {
-            project = null;
-            version = null;
-            issue = null;
-            updateAttributes();
-            project = new Project(-1);
-            updateAttributes();
-        }
-
-        void newVersion() throws SQLException {
-            project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
-            syncProject();
-            version = null;
-            issue = null;
-            updateAttributes();
-            version = new Version(-1);
-            version.setProject(project);
-            updateAttributes();
-        }
-
-        void newIssue() throws SQLException {
-            project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
-            syncProject();
-            version = null;
-            issue = null;
-            updateAttributes();
-            issue = new Issue(-1);
-            issue.setProject(project);
-            updateAttributes();
-        }
-
-        void selectVersion(Version selectedVersion) throws SQLException {
-            issue = null;
-            version = selectedVersion;
-            if (!version.getProject().equals(project)) {
-                project = dao.getProjectDao().find(version.getProject().getId());
-            }
-            // our object contains more details
-            version.setProject(project);
-            updateAttributes();
-        }
-
-        void selectIssue(Issue selectedIssue) throws SQLException {
-            issue = selectedIssue;
-            if (!issue.getProject().equals(project)) {
-                project = dao.getProjectDao().find(issue.getProject().getId());
-            }
-            // our object contains more details
-            issue.setProject(project);
-            if (!issue.getResolvedVersions().contains(version)
-                    && !issue.getAffectedVersions().contains(version)) {
-                version = null;
-            }
-            updateAttributes();
-        }
-
-        void syncProject() throws SQLException {
-            final var projectSelection = getParameter(req, Integer.class, "pid");
-            if (projectSelection.isPresent()) {
-                final var selectedProject = dao.getProjectDao().find(projectSelection.get());
-                if (!Objects.equals(selectedProject, project)) {
-                    // reset version and issue if project changed
-                    version = null;
-                    issue = null;
-                }
-                project = selectedProject;
-            } else {
-                project = project == null ? null : dao.getProjectDao().find(project.getId());
-            }
-        }
-
-        void syncVersion() throws SQLException {
-            final var versionSelection = getParameter(req, Integer.class, "vid");
-            if (versionSelection.isPresent()) {
-                if (versionSelection.get() < 0) {
-                    version = null;
-                } else {
-                    final var selectedVersion = dao.getVersionDao().find(versionSelection.get());
-                    if (!Objects.equals(selectedVersion, version)) {
-                        issue = null;
-                    }
-                    selectVersion(selectedVersion);
-                }
-            } else {
-                version = version == null ? null : dao.getVersionDao().find(version.getId());
-            }
-        }
-
-        void syncIssue() throws SQLException {
-            final var issueSelection = getParameter(req, Integer.class, "issue");
-            if (issueSelection.isPresent()) {
-                if (issueSelection.get() < 0) {
-                    issue = null;
-                } else {
-                    final var selectedIssue = dao.getIssueDao().find(issueSelection.get());
-                    dao.getIssueDao().joinVersionInformation(selectedIssue);
-                    selectIssue(selectedIssue);
-                }
-            } else {
-                issue = issue == null ? null : dao.getIssueDao().find(issue.getId());
-            }
-        }
-
-        void sync() throws SQLException {
-            project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
-            version = (Version) session.getAttribute(SESSION_ATTR_SELECTED_VERSION);
-            issue = (Issue) session.getAttribute(SESSION_ATTR_SELECTED_ISSUE);
-
-            syncProject();
-            syncVersion();
-            syncIssue();
-
-            updateAttributes();
-        }
-
-        private void updateAttributes() {
-            session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, project);
-            session.setAttribute(SESSION_ATTR_SELECTED_VERSION, version);
-            session.setAttribute(SESSION_ATTR_SELECTED_ISSUE, issue);
-        }
-    }
+    private static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project");
+    private static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version");
+    private static final String PARAMETER_SELECTED_PROJECT = "pid";
+    private static final String PARAMETER_SELECTED_VERSION = "vid";
 
     @Override
     protected String getResourceBundleName() {
         return "localization.projects";
     }
 
-    private String queryParams(Project p, Version v, Issue i) {
-        return String.format("pid=%d&vid=%d&issue=%d",
+    private String queryParams(Project p, Version v) {
+        return String.format("pid=%d&vid=%d",
                 p == null ? -1 : p.getId(),
-                v == null ? -1 : v.getId(),
-                i == null ? -1 : i.getId()
+                v == null ? -1 : v.getId()
         );
     }
 
     /**
      * Creates the navigation menu.
      *
-     * @param projects  the list of projects
-     * @param selection the currently selected objects
-     * @param projInfo  info about the currently selected project or null
-     * @return a dynamic navigation menu trying to display as many levels as possible
+     * @param req the servlet request
+     * @param viewModel the current view model
      */
-    private List<MenuEntry> getNavMenu(List<Project> projects, SessionSelection selection, ProjectInfo projInfo) {
+    private void setNavigationMenu(HttpServletRequest req, ProjectView viewModel) {
+        final Project selectedProject = Optional.ofNullable(viewModel.getProjectInfo()).map(ProjectInfo::getProject).orElse(null);
+
         final var navigation = new ArrayList<MenuEntry>();
 
-        for (Project proj : projects) {
+        for (ProjectInfo plistInfo : viewModel.getProjectList()) {
+            final var proj = plistInfo.getProject();
             final var projEntry = new MenuEntry(
                     proj.getName(),
-                    "projects/view?pid=" + proj.getId()
+                    "projects/view?" + queryParams(proj, null)
             );
             navigation.add(projEntry);
-            if (proj.equals(selection.project)) {
+            if (proj.equals(selectedProject)) {
+                final var projInfo = viewModel.getProjectInfo();
                 projEntry.setActive(true);
 
                 // ****************
@@ -239,8 +103,8 @@
                 // ****************
                 {
                     final var entry = new MenuEntry(1,
-                            new ResourceKey("localization.projects", "menu.versions"),
-                            "projects/view?" + queryParams(proj, null, null)
+                            new ResourceKey(getResourceBundleName(), "menu.versions"),
+                            "projects/view?" + queryParams(proj, null)
                     );
                     navigation.add(entry);
                 }
@@ -248,19 +112,19 @@
                 final var level2 = new ArrayList<MenuEntry>();
                 {
                     final var entry = new MenuEntry(
-                            new ResourceKey("localization.projects", "filter.all"),
-                            "projects/view?" + queryParams(proj, null, null)
+                            new ResourceKey(getResourceBundleName(), "filter.all"),
+                            "projects/view?" + queryParams(proj, null)
                     );
-                    if (selection.version == null) entry.setActive(true);
+                    if (viewModel.getVersionFilter() == null) entry.setActive(true);
                     level2.add(entry);
                 }
 
                 for (Version version : projInfo.getVersions()) {
                     final var entry = new MenuEntry(
                             version.getName(),
-                            "projects/versions/view?" + queryParams(proj, version, null)
+                            "projects/view?" + queryParams(proj, version)
                     );
-                    if (version.equals(selection.version)) entry.setActive(true);
+                    if (version.equals(viewModel.getVersionFilter())) entry.setActive(true);
                     level2.add(entry);
                 }
 
@@ -269,69 +133,85 @@
             }
         }
 
-        return navigation;
+        setNavigationMenu(req, navigation);
+    }
+
+    private int syncParamWithSession(HttpServletRequest req, String param, String attr) {
+        final var session = req.getSession();
+        final var idParam = getParameter(req, Integer.class, param);
+        final int id;
+        if (idParam.isPresent()) {
+            id = idParam.get();
+            session.setAttribute(attr, id);
+        } else {
+            id = Optional.ofNullable(session.getAttribute(attr)).map(x->(Integer)x).orElse(-1);
+        }
+        return id;
+    }
+
+    private void populate(ProjectView viewModel, HttpServletRequest req, DataAccessObjects dao) throws SQLException {
+        final var projectDao = dao.getProjectDao();
+        final var versionDao = dao.getVersionDao();
+
+        projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add);
+
+        // Select Project
+        final int pid = syncParamWithSession(req, PARAMETER_SELECTED_PROJECT, SESSION_ATTR_SELECTED_PROJECT);
+        if (pid >= 0) {
+            final var project = projectDao.find(pid);
+            final var info = new ProjectInfo(project);
+            info.setVersions(versionDao.list(project));
+            info.setIssueSummary(projectDao.getIssueSummary(project));
+            viewModel.setProjectInfo(info);
+        }
+
+        // Select Version
+        final int vid = syncParamWithSession(req, PARAMETER_SELECTED_VERSION, SESSION_ATTR_SELECTED_VERSION);
+        if (vid >= 0) {
+            viewModel.setVersionFilter(versionDao.find(vid));
+        }
+    }
+
+    private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) {
+        setViewModel(req, viewModel);
+        setContentPage(req, name);
+        setStylesheet(req, "projects");
+        setNavigationMenu(req, viewModel);
+        return ResponseType.HTML;
     }
 
     @RequestMapping(method = HttpMethod.GET)
     public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
-        final var sessionSelection = new SessionSelection(req, dao);
-        sessionSelection.sync();
+        final var viewModel = new ProjectView();
+        populate(viewModel, req, dao);
 
         final var projectDao = dao.getProjectDao();
         final var versionDao = dao.getVersionDao();
 
-        final var projectList = projectDao.list();
-
-        final var viewModel = new ProjectIndexView();
-        for (var project : projectList) {
-            final var info = new ProjectInfo(project);
-            info.setVersions(versionDao.list(project));
-            info.setIssueSummary(projectDao.getIssueSummary(project));
-            viewModel.getProjects().add(info);
+        for (var info : viewModel.getProjectList()) {
+            info.setVersions(versionDao.list(info.getProject()));
+            info.setIssueSummary(projectDao.getIssueSummary(info.getProject()));
         }
 
-        setViewModel(req, viewModel);
-        setContentPage(req, "projects");
-        setStylesheet(req, "projects");
-
-        setNavigationMenu(req, getNavMenu(projectList, sessionSelection, currentProjectInfo(dao, sessionSelection.project)));
-
-        return ResponseType.HTML;
+        return forwardView(req, viewModel, "projects");
     }
 
-    private ProjectInfo currentProjectInfo(DataAccessObjects dao, Project project) throws SQLException {
-        if (project == null) return null;
-        final var projectDao = dao.getProjectDao();
-        final var versionDao = dao.getVersionDao();
-
-        final var info = new ProjectInfo(project);
-        info.setVersions(versionDao.list(project));
-        info.setIssueSummary(projectDao.getIssueSummary(project));
-        return info;
-    }
-
-    private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
-        final var viewModel = new ProjectEditView();
-        viewModel.setProject(selection.project);
+    private void configure(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException {
+        viewModel.setProject(project);
         viewModel.setUsers(dao.getUserDao().list());
-        setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
-        setViewModel(req, viewModel);
-        setContentPage(req, "project-form");
-        return viewModel;
     }
 
     @RequestMapping(requestPath = "edit", method = HttpMethod.GET)
     public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
-        final var selection = new SessionSelection(req, dao);
-        if (getParameter(req, Integer.class, "pid").isEmpty()) {
-            selection.newProject();
-        } else {
-            selection.sync();
-        }
+        final var viewModel = new ProjectEditView();
+        populate(viewModel, req, dao);
 
-        configureEditForm(req, dao, selection);
+        final var project = Optional.ofNullable(viewModel.getProjectInfo())
+                .map(ProjectInfo::getProject)
+                .orElse(new Project(-1));
+        configure(viewModel, project, dao);
 
-        return ResponseType.HTML;
+        return forwardView(req, viewModel, "project-form");
     }
 
     @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
@@ -339,7 +219,7 @@
 
         Project project = new Project(-1);
         try {
-            project = new Project(getParameter(req, Integer.class, "id").orElseThrow());
+            project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
             project.setName(getParameter(req, String.class, "name").orElseThrow());
             getParameter(req, String.class, "description").ifPresent(project::setDescription);
             getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
@@ -349,99 +229,61 @@
 
             dao.getProjectDao().saveOrUpdate(project);
 
-            setRedirectLocation(req, "./projects/");
+            setRedirectLocation(req, "./projects/view?pid="+project.getId());
             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
             LOG.debug("Successfully updated project {}", project.getName());
+
+            return ResponseType.HTML;
         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
             LOG.warn("Form validation failure: {}", ex.getMessage());
             LOG.debug("Details:", ex);
-            final var selection = new SessionSelection(req, dao);
-            selection.project = project;
-            final var vm = configureEditForm(req, dao, selection);
-            vm.setErrorText(ex.getMessage()); // TODO: error text
+            final var viewModel = new ProjectEditView();
+            populate(viewModel, req, dao);
+            configure(viewModel, project, dao);
+            // TODO: error text
+            return forwardView(req, viewModel, "project-form");
         }
-
-        return ResponseType.HTML;
     }
 
     @RequestMapping(requestPath = "view", method = HttpMethod.GET)
     public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
-        final var selection = new SessionSelection(req, dao);
-        selection.sync();
+        final var viewModel = new ProjectDetailsView();
+        populate(viewModel, req, dao);
 
-        if (selection.project == null) {
+        if (viewModel.getProjectInfo() == null) {
             resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected.");
             return ResponseType.NONE;
         }
 
-        final var projectDao = dao.getProjectDao();
-        final var versionDao = dao.getVersionDao();
         final var issueDao = dao.getIssueDao();
 
-        final var viewModel = new ProjectView(selection.project);
-        final var issues = issueDao.list(selection.project);
-        for (var issue : issues) issueDao.joinVersionInformation(issue);
-        viewModel.setIssues(issues);
-        // TODO: fix duplicated selection of versions (projectInfo also contains these infos)
-        viewModel.setVersions(versionDao.list(selection.project));
-        viewModel.updateVersionInfo();
-        setViewModel(req, viewModel);
-
-        setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
-        setContentPage(req, "project-details");
-        setStylesheet(req, "projects");
-
-        return ResponseType.HTML;
-    }
-
-    @RequestMapping(requestPath = "versions/view", method = HttpMethod.GET)
-    public ResponseType viewVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
-        final var selection = new SessionSelection(req, dao);
-        selection.sync();
-        if (selection.version == null) {
-            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
-            return ResponseType.NONE;
-        }
+        final var project = viewModel.getProjectInfo().getProject();
 
-        final var projectDao = dao.getProjectDao();
-        final var issueDao = dao.getIssueDao();
-
-        final var viewModel = new VersionView(selection.version);
-        final var issues = issueDao.list(selection.version);
+        final var detailView = viewModel.getProjectDetails();
+        if (viewModel.getVersionFilter() != null) {
+            detailView.updateVersionInfo(List.of(viewModel.getVersionFilter()));
+        } else {
+            detailView.updateVersionInfo(viewModel.getProjectInfo().getVersions());
+        }
+        final var issues = issueDao.list(project);
         for (var issue : issues) issueDao.joinVersionInformation(issue);
-        viewModel.setIssues(issues);
-        setViewModel(req, viewModel);
-
-        setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
-        setContentPage(req, "version");
-        setStylesheet(req, "projects");
+        detailView.setIssues(issues);
 
-        return ResponseType.HTML;
-    }
-
-    private VersionEditView configureEditVersionForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
-        final var viewModel = new VersionEditView(selection.version);
-        if (selection.version.getProject() == null) {
-            viewModel.setProjects(dao.getProjectDao().list());
-        }
-        setViewModel(req, viewModel);
-        setContentPage(req, "version-form");
-        setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
-        return viewModel;
+        return forwardView(req, viewModel, "project-details");
     }
 
     @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET)
     public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
-        final var selection = new SessionSelection(req, dao);
-        if (getParameter(req, Integer.class, "vid").isEmpty()) {
-            selection.newVersion();
+        final var viewModel = new VersionEditView();
+        populate(viewModel, req, dao);
+
+        if (viewModel.getVersionFilter() == null) {
+            viewModel.setVersion(new Version(-1));
         } else {
-            selection.sync();
+            viewModel.setVersion(viewModel.getVersionFilter());
         }
 
-        configureEditVersionForm(req, dao, selection);
-
-        return ResponseType.HTML;
+        return forwardView(req, viewModel, "version-form");
     }
 
     @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST)
@@ -462,77 +304,43 @@
         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
             LOG.warn("Form validation failure: {}", ex.getMessage());
             LOG.debug("Details:", ex);
-            final var selection = new SessionSelection(req, dao);
-            selection.selectVersion(version);
-            final var viewModel = configureEditVersionForm(req, dao, selection);
+            final var viewModel = new VersionEditView();
+            populate(viewModel, req, dao);
+            viewModel.setVersion(version);
             // TODO: set Error Text
+            return forwardView(req, viewModel, "version-form");
         }
 
         return ResponseType.HTML;
     }
 
-    private IssueEditView configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
-        final var viewModel = new IssueEditView(selection.issue);
-
-        if (selection.issue.getProject() == null) {
-            viewModel.setProjects(dao.getProjectDao().list());
-        } else {
-            viewModel.setVersions(dao.getVersionDao().list(selection.issue.getProject()));
-        }
+    private void configure(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException {
+        issue.setProject(viewModel.getProjectInfo().getProject());
+        viewModel.setIssue(issue);
+        viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions());
         viewModel.setUsers(dao.getUserDao().list());
-        setViewModel(req, viewModel);
-
-        setContentPage(req, "issue-form");
-        setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
-        return viewModel;
-    }
-
-    @RequestMapping(requestPath = "issues/", method = HttpMethod.GET)
-    public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
-        final var selection = new SessionSelection(req, dao);
-        selection.sync();
-        if (selection.project == null) {
-            resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected.");
-            return ResponseType.NONE;
-        }
-
-        final var projectDao = dao.getProjectDao();
-        final var issueDao = dao.getIssueDao();
-
-        final var viewModel = new IssuesView();
-        viewModel.setProject(selection.project);
-        if (selection.version == null) {
-            viewModel.setIssues(issueDao.list(selection.project));
-        } else {
-            viewModel.setVersion(selection.version);
-            viewModel.setIssues(issueDao.list(selection.version));
-        }
-        setViewModel(req, viewModel);
-
-        setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
-        setContentPage(req, "issues");
-        setStylesheet(req, "projects");
-
-        return ResponseType.HTML;
     }
 
     @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET)
     public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException {
-        final var selection = new SessionSelection(req, dao);
-        if (getParameter(req, Integer.class, "issue").isEmpty()) {
-            selection.newIssue();
+        final var viewModel = new IssueEditView();
+
+        final var issueParam = getParameter(req, Integer.class, "issue");
+        if (issueParam.isPresent()) {
+            final var issue = dao.getIssueDao().find(issueParam.get());
+            req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, issue.getProject().getId());
+            populate(viewModel, req, dao);
+            configure(viewModel, issue, dao);
         } else {
-            selection.sync();
+            populate(viewModel, req, dao);
+            configure(viewModel, new Issue(-1), dao);
         }
 
-        configureEditIssueForm(req, dao, selection);
-
-        return ResponseType.HTML;
+        return forwardView(req, viewModel, "issue-form");
     }
 
     @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST)
     public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException {
-
         Issue issue = new Issue(-1);
         try {
             issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
@@ -560,16 +368,16 @@
             dao.getIssueDao().saveOrUpdate(issue);
 
             // specifying the issue parameter keeps the edited issue as menu item
-            setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId());
+            setRedirectLocation(req, "./projects/view/?pid=" + issue.getProject().getId());
             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
             // TODO: set request attribute with error text
             LOG.warn("Form validation failure: {}", ex.getMessage());
             LOG.debug("Details:", ex);
-            final var selection = new SessionSelection(req, dao);
-            selection.selectIssue(issue);
-            final var viewModel = configureEditIssueForm(req, dao, selection);
+            final var viewModel = new IssueEditView();
+            configure(viewModel, issue, dao);
             // TODO: set Error Text
+            return forwardView(req, viewModel, "issue-form");
         }
 
         return ResponseType.HTML;

mercurial