diff -r ef075cd7ce55 -r f47e82cd6077 src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sat Oct 17 15:21:56 2020 +0200 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sat Oct 17 19:56:50 2020 +0200 @@ -32,6 +32,7 @@ import de.uapcore.lightpit.*; import de.uapcore.lightpit.dao.DataAccessObjects; import de.uapcore.lightpit.entities.*; +import de.uapcore.lightpit.types.WebColor; import de.uapcore.lightpit.viewmodel.*; import de.uapcore.lightpit.viewmodel.util.IssueSorter; import org.slf4j.Logger; @@ -43,6 +44,7 @@ import java.io.IOException; import java.sql.Date; import java.sql.SQLException; +import java.util.List; import java.util.NoSuchElementException; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -84,19 +86,30 @@ } // Select Version - final int vid = Functions.parseIntOrZero(pathParameters.get("version")); - if (vid > 0) { - viewModel.setVersionFilter(versionDao.find(vid)); + final var pathParamVersion = pathParameters.get("version"); + if ("no-version".equals(pathParamVersion)) { + viewModel.setVersionFilter(ProjectView.NO_VERSION); + } else if ("all-versions".equals(pathParamVersion)) { + viewModel.setVersionFilter(ProjectView.ALL_VERSIONS); + } else { + final int vid = Functions.parseIntOrZero(pathParamVersion); + if (vid > 0) { + viewModel.setVersionFilter(versionDao.find(vid)); + } } - // TODO: don't treat unknown == unassigned - send 404 for unknown and introduce special word for unassigned // Select Component - final int cid = Functions.parseIntOrZero(pathParameters.get("component")); - if (cid > 0) { - viewModel.setComponentFilter(componentDao.find(cid)); + final var pathParamComponent = pathParameters.get("component"); + if ("no-component".equals(pathParamComponent)) { + viewModel.setComponentFilter(ProjectView.NO_COMPONENT); + } else if ("all-components".equals(pathParamComponent)) { + viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS); + } else { + final int cid = Functions.parseIntOrZero(pathParamComponent); + if (cid > 0) { + viewModel.setComponentFilter(componentDao.find(cid)); + } } - - // TODO: distinguish all/unassigned for components } private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) { @@ -133,7 +146,7 @@ final var viewModel = new ProjectEditView(); populate(viewModel, pathParams, dao); - if (viewModel.getProjectInfo() == null) { + if (!viewModel.isProjectInfoPresent()) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return ResponseType.NONE; } @@ -176,28 +189,60 @@ } } - @RequestMapping(requestPath = "$project/versions/$version", method = HttpMethod.GET) - public ResponseType view(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException { + @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET) + public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException { final var viewModel = new ProjectDetailsView(); populate(viewModel, pathParams, dao); - final var version = viewModel.getVersionFilter(); - if (viewModel.getProjectInfo() == null || version == null) { + if (!viewModel.isEveryFilterValid()) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return ResponseType.NONE; } + final var project = viewModel.getProjectInfo().getProject(); + final var version = viewModel.getVersionFilter(); + final var component = viewModel.getComponentFilter(); + final var issueDao = dao.getIssueDao(); - final var detailView = viewModel.getProjectDetails(); - final var issues = issueDao.list(version); + final List issues; + if (version.equals(ProjectView.NO_VERSION)) { + if (component.equals(ProjectView.ALL_COMPONENTS)) { + issues = issueDao.list(project, (Version) null); + } else if (component.equals(ProjectView.NO_COMPONENT)) { + issues = issueDao.list(project, null, null); + } else { + issues = issueDao.list(project, component, null); + } + } else if (version.equals(ProjectView.ALL_VERSIONS)) { + if (component.equals(ProjectView.ALL_COMPONENTS)) { + issues = issueDao.list(project); + } else if (component.equals(ProjectView.NO_COMPONENT)) { + issues = issueDao.list(project, (Component)null); + } else { + issues = issueDao.list(project, component); + } + } else { + if (component.equals(ProjectView.ALL_COMPONENTS)) { + issues = issueDao.list(project, version); + } else if (component.equals(ProjectView.NO_COMPONENT)) { + issues = issueDao.list(project, null, version); + } else { + issues = issueDao.list(project, component, version); + } + } + for (var issue : issues) issueDao.joinVersionInformation(issue); issues.sort(new IssueSorter( new IssueSorter.Criteria(IssueSorter.Field.PHASE, true), new IssueSorter.Criteria(IssueSorter.Field.ETA, true), new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false) )); - detailView.updateDetails(issues, version); + + + viewModel.getProjectDetails().updateDetails(issues); + if (version.getId() > 0) + viewModel.getProjectDetails().updateVersionInfo(version); return forwardView(req, viewModel, "project-details"); } @@ -262,7 +307,6 @@ version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); dao.getVersionDao().saveOrUpdate(version, project); - // TODO: improve building the redirect location setRedirectLocation(req, "./projects/" + project.getId() + "/versions/"); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { @@ -274,11 +318,90 @@ return ResponseType.HTML; } + @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET) + public ResponseType components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException { + final var viewModel = new ComponentsView(); + populate(viewModel, pathParameters, dao); + + final var projectInfo = viewModel.getProjectInfo(); + if (projectInfo == null) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + return ResponseType.NONE; + } + + final var issueDao = dao.getIssueDao(); + final var issues = issueDao.list(projectInfo.getProject()); + viewModel.update(projectInfo.getComponents(), issues); + + return forwardView(req, viewModel, "components"); + } + + @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET) + public ResponseType editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException { + final var viewModel = new ComponentEditView(); + populate(viewModel, pathParameters, dao); + + if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + return ResponseType.NONE; + } + + viewModel.setComponent(viewModel.getComponentFilter()); + viewModel.setUsers(dao.getUserDao().list()); + + return forwardView(req, viewModel, "component-form"); + } + + @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET) + public ResponseType createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException { + final var viewModel = new ComponentEditView(); + populate(viewModel, pathParameters, dao); + + if (viewModel.getProjectInfo() == null) { + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + return ResponseType.NONE; + } + + viewModel.setComponent(new Component(-1)); + viewModel.setUsers(dao.getUserDao().list()); + + return forwardView(req, viewModel, "component-form"); + } + + @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST) + public ResponseType commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException { + + try { + final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); + final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow()); + component.setName(getParameter(req, String.class, "name").orElseThrow()); + component.setColor(getParameter(req, WebColor.class, "color").orElseThrow()); + getParameter(req, Integer.class, "ordinal").ifPresent(component::setOrdinal); + getParameter(req, Integer.class, "lead").map( + userid -> userid >= 0 ? new User(userid) : null + ).ifPresent(component::setLead); + getParameter(req, String.class, "description").ifPresent(component::setDescription); + + dao.getComponentDao().saveOrUpdate(component, project); + + setRedirectLocation(req, "./projects/" + project.getId() + "/components/"); + setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); + } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { + resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); + // TODO: implement - fix issue #21 + return ResponseType.NONE; + } + + return ResponseType.HTML; + } + private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException { - issue.setProject(viewModel.getProjectInfo().getProject()); + final var project = viewModel.getProjectInfo().getProject(); + issue.setProject(project); viewModel.setIssue(issue); viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); viewModel.setUsers(dao.getUserDao().list()); + viewModel.setComponents(dao.getComponentDao().list(project)); if (issue.getId() >= 0) { viewModel.setComments(dao.getIssueDao().listComments(issue)); } @@ -337,6 +460,9 @@ getParameter(req, Integer.class, "assignee").map( userid -> userid >= 0 ? new User(userid) : null ).ifPresent(issue::setAssignee); + getParameter(req, Integer.class, "component").map( + cid -> cid >= 0 ? new Component(cid) : null + ).ifPresent(issue::setComponent); getParameter(req, String.class, "description").ifPresent(issue::setDescription); getParameter(req, Date.class, "eta").ifPresent(issue::setEta); @@ -354,7 +480,7 @@ dao.getIssueDao().saveOrUpdate(issue, issue.getProject()); // TODO: fix issue #14 - setRedirectLocation(req, "./projects/" + issue.getProject().getId() + "/versions/"); + setRedirectLocation(req, "./projects/" + issue.getProject().getId() + "/all-components/all-versions/issues/"); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); return ResponseType.HTML;