diff -r 821c4950b619 -r dca186d3911f src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Tue May 19 19:34:57 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Fri May 22 16:21:31 2020 +0200 @@ -40,7 +40,10 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; import java.util.NoSuchElementException; +import java.util.Optional; import static de.uapcore.lightpit.Functions.fqn; @@ -63,14 +66,44 @@ final var projectDao = dao.getProjectDao(); final var session = req.getSession(); final var projectSelection = getParameter(req, Integer.class, "pid"); + final Project selectedProject; if (projectSelection.isPresent()) { - final var selectedId = projectSelection.get(); - final var selectedProject = projectDao.find(selectedId); - session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, selectedProject); - return selectedProject; + selectedProject = projectDao.find(projectSelection.get()); } else { - return (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); + final var sessionProject = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); + selectedProject = sessionProject == null ? null : projectDao.find(sessionProject.getId()); } + session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, selectedProject); + return selectedProject; + } + + + /** + * Creates the breadcrumb menu. + * + * @param level the current active level + * @param selectedProject the selected project, if any, or null + * @return a dynamic breadcrumb menu trying to display as many levels as possible + */ + private List getBreadcrumbs(int level, + Project selectedProject) { + MenuEntry entry; + + final var breadcrumbs = new ArrayList(); + entry = new MenuEntry(new ResourceKey("localization.projects", "menuLabel"), + "projects/", 0); + breadcrumbs.add(entry); + if (level == 0) entry.setActive(true); + + if (selectedProject == null) + return breadcrumbs; + + entry = new MenuEntry(selectedProject.getName(), + "projects/view?pid=" + selectedProject.getId(), 1); + if (level == 1) entry.setActive(true); + + breadcrumbs.add(entry); + return breadcrumbs; } @RequestMapping(method = HttpMethod.GET) @@ -81,20 +114,33 @@ setDynamicFragment(req, "projects"); setStylesheet(req, "projects"); - if (getSelectedProject(req, dao) == null) { - projectList.stream().findFirst().ifPresent(proj -> req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, proj)); - } + final var selectedProject = getSelectedProject(req, dao); + setBreadcrumbs(req, getBreadcrumbs(0, selectedProject)); return ResponseType.HTML; } + private void configureEditForm(HttpServletRequest req, DataAccessObjects dao, Optional project) throws SQLException { + if (project.isPresent()) { + req.setAttribute("project", project.get()); + setBreadcrumbs(req, getBreadcrumbs(1, project.get())); + } else { + req.setAttribute("project", new Project(-1)); + setBreadcrumbs(req, getBreadcrumbs(0, null)); + } + + req.setAttribute("users", dao.getUserDao().list()); + setDynamicFragment(req, "project-form"); + } + @RequestMapping(requestPath = "edit", method = HttpMethod.GET) public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { - req.setAttribute("project", findByParameter(req, Integer.class, "id", - dao.getProjectDao()::find).orElse(new Project(-1))); - req.setAttribute("users", dao.getUserDao().list()); - setDynamicFragment(req, "project-form"); + Optional project = findByParameter(req, Integer.class, "id", dao.getProjectDao()::find); + configureEditForm(req, dao, project); + if (project.isPresent()) { + req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, project.get()); + } return ResponseType.HTML; } @@ -102,7 +148,7 @@ @RequestMapping(requestPath = "commit", method = HttpMethod.POST) public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { - Project project = new Project(-1); + Project project = null; try { project = new Project(getParameter(req, Integer.class, "id").orElseThrow()); project.setName(getParameter(req, String.class, "name").orElseThrow()); @@ -119,11 +165,9 @@ LOG.debug("Successfully updated project {}", project.getName()); } catch (NoSuchElementException | NumberFormatException | SQLException ex) { // TODO: set request attribute with error text - req.setAttribute("project", project); - req.setAttribute("users", dao.getUserDao().list()); - setDynamicFragment(req, "project-form"); LOG.warn("Form validation failure: {}", ex.getMessage()); LOG.debug("Details:", ex); + configureEditForm(req, dao, Optional.ofNullable(project)); } return ResponseType.HTML; @@ -140,11 +184,21 @@ req.setAttribute("versions", dao.getVersionDao().list(selectedProject)); req.setAttribute("issues", dao.getIssueDao().list(selectedProject)); + // TODO: add more levels depending on last visited location + setBreadcrumbs(req, getBreadcrumbs(1, selectedProject)); + setDynamicFragment(req, "project-details"); return ResponseType.HTML; } + private void configureEditVersionForm(HttpServletRequest req, Optional version, Project selectedProject) { + req.setAttribute("version", version.orElse(new Version(-1, selectedProject))); + req.setAttribute("versionStatusEnum", VersionStatus.values()); + + setDynamicFragment(req, "version-form"); + } + @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) public ResponseType editVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException { final var selectedProject = getSelectedProject(req, dao); @@ -153,11 +207,9 @@ return ResponseType.NONE; } - req.setAttribute("version", findByParameter(req, Integer.class, "id", - dao.getVersionDao()::find).orElse(new Version(-1, selectedProject))); - req.setAttribute("versionStatusEnum", VersionStatus.values()); - - setDynamicFragment(req, "version-form"); + configureEditVersionForm(req, + findByParameter(req, Integer.class, "id", dao.getVersionDao()::find), + selectedProject); return ResponseType.HTML; } @@ -170,7 +222,7 @@ return ResponseType.NONE; } - Version version = new Version(-1, selectedProject); + Version version = null; try { version = new Version(getParameter(req, Integer.class, "id").orElseThrow(), selectedProject); version.setName(getParameter(req, String.class, "name").orElseThrow()); @@ -183,16 +235,24 @@ LOG.debug("Successfully updated version {} for project {}", version.getName(), selectedProject.getName()); } catch (NoSuchElementException | NumberFormatException | SQLException ex) { // TODO: set request attribute with error text - req.setAttribute("version", version); - req.setAttribute("versionStatusEnum", VersionStatus.values()); - setDynamicFragment(req, "version-form"); LOG.warn("Form validation failure: {}", ex.getMessage()); LOG.debug("Details:", ex); + configureEditVersionForm(req, Optional.ofNullable(version), selectedProject); } return ResponseType.HTML; } + private void configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, Optional issue, Project selectedProject) throws SQLException { + + req.setAttribute("issue", issue.orElse(new Issue(-1, selectedProject))); + req.setAttribute("issueStatusEnum", IssueStatus.values()); + req.setAttribute("issueCategoryEnum", IssueCategory.values()); + req.setAttribute("versions", dao.getVersionDao().list(selectedProject)); + + setDynamicFragment(req, "issue-form"); + } + @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET) public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException { final var selectedProject = getSelectedProject(req, dao); @@ -201,12 +261,9 @@ return ResponseType.NONE; } - req.setAttribute("issue", findByParameter(req, Integer.class, "id", - dao.getIssueDao()::find).orElse(new Issue(-1, selectedProject))); - req.setAttribute("issueStatusEnum", IssueStatus.values()); - req.setAttribute("issueCategoryEnum", IssueCategory.values()); - - setDynamicFragment(req, "issue-form"); + configureEditIssueForm(req, dao, + findByParameter(req, Integer.class, "id", dao.getIssueDao()::find), + selectedProject); return ResponseType.HTML; } @@ -219,7 +276,7 @@ return ResponseType.NONE; } - Issue issue = new Issue(-1, selectedProject); + Issue issue = null; try { issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow(), selectedProject); @@ -232,12 +289,9 @@ LOG.debug("Successfully updated issue {} for project {}", issue.getId(), selectedProject.getName()); } catch (NoSuchElementException | NumberFormatException | SQLException ex) { // TODO: set request attribute with error text - req.setAttribute("issue", issue); - req.setAttribute("issueStatusEnum", IssueStatus.values()); - req.setAttribute("issueCategoryEnum", IssueCategory.values()); - setDynamicFragment(req, "issue-form"); LOG.warn("Form validation failure: {}", ex.getMessage()); LOG.debug("Details:", ex); + configureEditIssueForm(req, dao, Optional.ofNullable(issue), selectedProject); } return ResponseType.HTML;