diff -r 6eede6088d41 -r 3f30adba1c63 src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sun Dec 20 11:06:25 2020 +0100 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Mon Dec 21 18:29:34 2020 +0100 @@ -30,8 +30,15 @@ import de.uapcore.lightpit.*; -import de.uapcore.lightpit.dao.DaoProvider; +import de.uapcore.lightpit.dao.DataAccessObject; import de.uapcore.lightpit.entities.*; +import de.uapcore.lightpit.filter.AllFilter; +import de.uapcore.lightpit.filter.IssueFilter; +import de.uapcore.lightpit.filter.NoneFilter; +import de.uapcore.lightpit.filter.SpecificFilter; +import de.uapcore.lightpit.types.IssueCategory; +import de.uapcore.lightpit.types.IssueStatus; +import de.uapcore.lightpit.types.VersionStatus; import de.uapcore.lightpit.types.WebColor; import de.uapcore.lightpit.viewmodel.*; import de.uapcore.lightpit.viewmodel.util.IssueSorter; @@ -45,7 +52,6 @@ import java.io.IOException; import java.sql.Date; import java.sql.SQLException; -import java.util.List; import java.util.NoSuchElementException; import java.util.Optional; import java.util.stream.Collectors; @@ -72,25 +78,21 @@ } } - private void populate(ProjectView viewModel, PathParameters pathParameters, DaoProvider dao) { - final var projectDao = dao.getProjectDao(); - final var versionDao = dao.getVersionDao(); - final var componentDao = dao.getComponentDao(); - - projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); + private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObject dao) { + dao.listProjects().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); if (pathParameters == null) return; // Select Project - final var project = projectDao.findByNode(pathParameters.get("project")); + final var project = dao.findProjectByNode(pathParameters.get("project")); if (project == null) return; final var info = new ProjectInfo(project); - info.setVersions(versionDao.list(project)); - info.setComponents(componentDao.list(project)); - info.setIssueSummary(projectDao.getIssueSummary(project)); + info.setVersions(dao.listVersions(project)); + info.setComponents(dao.listComponents(project)); + info.setIssueSummary(dao.collectIssueSummary(project)); viewModel.setProjectInfo(info); // Select Version @@ -101,7 +103,7 @@ } else if ("all-versions".equals(versionNode)) { viewModel.setVersionFilter(ProjectView.ALL_VERSIONS); } else { - viewModel.setVersionFilter(versionDao.findByNode(project, versionNode)); + viewModel.setVersionFilter(dao.findVersionByNode(project, versionNode)); } } @@ -113,7 +115,7 @@ } else if ("all-components".equals(componentNode)) { viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS); } else { - viewModel.setComponentFilter(componentDao.findByNode(project, componentNode)); + viewModel.setComponentFilter(dao.findComponentByNode(project, componentNode)); } } } @@ -137,28 +139,25 @@ } @RequestMapping(method = HttpMethod.GET) - public void index(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { + public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws ServletException, IOException { final var viewModel = new ProjectView(); populate(viewModel, null, dao); - final var projectDao = dao.getProjectDao(); - final var versionDao = dao.getVersionDao(); - for (var info : viewModel.getProjectList()) { - info.setVersions(versionDao.list(info.getProject())); - info.setIssueSummary(projectDao.getIssueSummary(info.getProject())); + info.setVersions(dao.listVersions(info.getProject())); + info.setIssueSummary(dao.collectIssueSummary(info.getProject())); } forwardView(req, resp, viewModel, "projects"); } - private void configureProjectEditor(ProjectEditView viewModel, Project project, DaoProvider dao) throws SQLException { + private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObject dao) { viewModel.setProject(project); - viewModel.setUsers(dao.getUserDao().list()); + viewModel.setUsers(dao.listUsers()); } @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET) - public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws IOException, SQLException, ServletException { + public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObject dao) throws IOException, SQLException, ServletException { final var viewModel = new ProjectEditView(); populate(viewModel, pathParams, dao); @@ -172,7 +171,7 @@ } @RequestMapping(requestPath = "create", method = HttpMethod.GET) - public void create(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { + public void create(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws SQLException, ServletException, IOException { final var viewModel = new ProjectEditView(); populate(viewModel, null, dao); configureProjectEditor(viewModel, new Project(-1), dao); @@ -180,7 +179,7 @@ } @RequestMapping(requestPath = "commit", method = HttpMethod.POST) - public void commit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { + public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { try { final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); @@ -195,12 +194,10 @@ ownerId -> ownerId >= 0 ? new User(ownerId) : null ).ifPresent(project::setOwner); - final var projectDao = dao.getProjectDao(); if (project.getId() > 0) { - // TODO: unused return value - projectDao.update(project); + dao.updateProject(project); } else { - projectDao.save(project); + dao.insertProject(project); } setRedirectLocation(req, "./projects/"); @@ -215,7 +212,7 @@ } @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET) - public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws SQLException, IOException, ServletException { + public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObject dao) throws SQLException, IOException, ServletException { final var viewModel = new ProjectDetailsView(); populate(viewModel, pathParams, dao); @@ -228,36 +225,64 @@ final var version = viewModel.getVersionFilter(); final var component = viewModel.getComponentFilter(); - final var issueDao = dao.getIssueDao(); + // TODO: use new IssueFilter class for the ViewModel - final List issues; + final var projectFilter = new SpecificFilter<>(project); + final IssueFilter filter; if (version.equals(ProjectView.NO_VERSION)) { if (component.equals(ProjectView.ALL_COMPONENTS)) { - issues = issueDao.list(project, (Version) null); + filter = new IssueFilter(projectFilter, + new NoneFilter<>(), + new AllFilter<>() + ); } else if (component.equals(ProjectView.NO_COMPONENT)) { - issues = issueDao.list(project, null, null); + filter = new IssueFilter(projectFilter, + new NoneFilter<>(), + new NoneFilter<>() + ); } else { - issues = issueDao.list(project, component, null); + filter = new IssueFilter(projectFilter, + new NoneFilter<>(), + new SpecificFilter<>(component) + ); } } else if (version.equals(ProjectView.ALL_VERSIONS)) { if (component.equals(ProjectView.ALL_COMPONENTS)) { - issues = issueDao.list(project); + filter = new IssueFilter(projectFilter, + new AllFilter<>(), + new AllFilter<>() + ); } else if (component.equals(ProjectView.NO_COMPONENT)) { - issues = issueDao.list(project, (Component)null); + filter = new IssueFilter(projectFilter, + new AllFilter<>(), + new NoneFilter<>() + ); } else { - issues = issueDao.list(project, component); + filter = new IssueFilter(projectFilter, + new AllFilter<>(), + new SpecificFilter<>(component) + ); } } else { if (component.equals(ProjectView.ALL_COMPONENTS)) { - issues = issueDao.list(project, version); + filter = new IssueFilter(projectFilter, + new SpecificFilter<>(version), + new AllFilter<>() + ); } else if (component.equals(ProjectView.NO_COMPONENT)) { - issues = issueDao.list(project, null, version); + filter = new IssueFilter(projectFilter, + new SpecificFilter<>(version), + new NoneFilter<>() + ); } else { - issues = issueDao.list(project, component, version); + filter = new IssueFilter(projectFilter, + new SpecificFilter<>(version), + new SpecificFilter<>(component) + ); } } - for (var issue : issues) issueDao.joinVersionInformation(issue); + final var issues = dao.listIssues(filter); issues.sort(new IssueSorter( new IssueSorter.Criteria(IssueSorter.Field.DONE, true), new IssueSorter.Criteria(IssueSorter.Field.ETA, true), @@ -273,7 +298,7 @@ } @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET) - public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { final var viewModel = new VersionsView(); populate(viewModel, pathParameters, dao); @@ -283,16 +308,20 @@ return; } - final var issueDao = dao.getIssueDao(); - final var issues = issueDao.list(projectInfo.getProject()); - for (var issue : issues) issueDao.joinVersionInformation(issue); + final var issues = dao.listIssues( + new IssueFilter( + new SpecificFilter<>(projectInfo.getProject()), + new AllFilter<>(), + new AllFilter<>() + ) + ); viewModel.update(projectInfo.getVersions(), issues); forwardView(req, resp, viewModel, "versions"); } @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET) - public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { final var viewModel = new VersionEditView(); populate(viewModel, pathParameters, dao); @@ -307,7 +336,7 @@ } @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET) - public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { final var viewModel = new VersionEditView(); populate(viewModel, pathParameters, dao); @@ -316,22 +345,22 @@ return; } - viewModel.setVersion(new Version(-1)); + viewModel.setVersion(new Version(-1, viewModel.getProjectInfo().getProject().getId())); forwardView(req, resp, viewModel, "version-form"); } @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST) - public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { + public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { try { - final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); + final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); if (project == null) { // TODO: improve error handling, because not found is not correct for this POST request resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow()); + final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow(), project.getId()); version.setName(getParameter(req, String.class, "name").orElseThrow()); final var node = getParameter(req, String.class, "node").orElse(null); @@ -340,12 +369,10 @@ getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); - final var versionDao = dao.getVersionDao(); if (version.getId() > 0) { - // TODO: use return value - versionDao.update(version); + dao.updateVersion(version); } else { - versionDao.save(version, project); + dao.insertVersion(version); } setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/"); @@ -359,7 +386,7 @@ } @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET) - public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { final var viewModel = new ComponentsView(); populate(viewModel, pathParameters, dao); @@ -369,15 +396,20 @@ return; } - final var issueDao = dao.getIssueDao(); - final var issues = issueDao.list(projectInfo.getProject()); + final var issues = dao.listIssues( + new IssueFilter( + new SpecificFilter<>(projectInfo.getProject()), + new AllFilter<>(), + new AllFilter<>() + ) + ); viewModel.update(projectInfo.getComponents(), issues); forwardView(req, resp, viewModel, "components"); } @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET) - public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { final var viewModel = new ComponentEditView(); populate(viewModel, pathParameters, dao); @@ -387,13 +419,13 @@ } viewModel.setComponent(viewModel.getComponentFilter()); - viewModel.setUsers(dao.getUserDao().list()); + viewModel.setUsers(dao.listUsers()); forwardView(req, resp, viewModel, "component-form"); } @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET) - public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { final var viewModel = new ComponentEditView(); populate(viewModel, pathParameters, dao); @@ -402,23 +434,23 @@ return; } - viewModel.setComponent(new Component(-1)); - viewModel.setUsers(dao.getUserDao().list()); + viewModel.setComponent(new Component(-1, viewModel.getProjectInfo().getProject().getId())); + viewModel.setUsers(dao.listUsers()); forwardView(req, resp, viewModel, "component-form"); } @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST) - public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { + public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { try { - final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); + final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); if (project == null) { // TODO: improve error handling, because not found is not correct for this POST request resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow()); + final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow(), project.getId()); component.setName(getParameter(req, String.class, "name").orElseThrow()); final var node = getParameter(req, String.class, "node").orElse(null); @@ -431,12 +463,10 @@ ).ifPresent(component::setLead); getParameter(req, String.class, "description").ifPresent(component::setDescription); - final var componentDao = dao.getComponentDao(); if (component.getId() > 0) { - // TODO: use return value - componentDao.update(component); + dao.updateComponent(component); } else { - componentDao.save(component, project); + dao.insertComponent(component); } setRedirectLocation(req, "./projects/" + project.getNode() + "/components/"); @@ -449,17 +479,17 @@ } } - private void configureIssueEditor(IssueEditView viewModel, Issue issue, DaoProvider dao) throws SQLException { + private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObject dao) { final var project = viewModel.getProjectInfo().getProject(); issue.setProject(project); // automatically set current project for new issues viewModel.setIssue(issue); viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); - viewModel.setUsers(dao.getUserDao().list()); - viewModel.setComponents(dao.getComponentDao().list(project)); + viewModel.setUsers(dao.listUsers()); + viewModel.setComponents(dao.listComponents(project)); } @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET) - public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { final var viewModel = new IssueDetailView(); populate(viewModel, pathParameters, dao); @@ -469,16 +499,14 @@ return; } - final var issueDao = dao.getIssueDao(); - final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); + final var issue = dao.findIssue(parseIntOrZero(pathParameters.get("issue"))); if (issue == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - issueDao.joinVersionInformation(issue); viewModel.setIssue(issue); - viewModel.setComments(issueDao.listComments(issue)); + viewModel.setComments(dao.listComments(issue)); viewModel.processMarkdown(); @@ -487,7 +515,7 @@ // TODO: why should the issue editor be child of $project? @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET) - public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { final var viewModel = new IssueEditView(); populate(viewModel, pathParameters, dao); @@ -497,21 +525,19 @@ return; } - final var issueDao = dao.getIssueDao(); - final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); + final var issue = dao.findIssue(parseIntOrZero(pathParameters.get("issue"))); if (issue == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - issueDao.joinVersionInformation(issue); configureIssueEditor(viewModel, issue, dao); forwardView(req, resp, viewModel, "issue-form"); } @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET) - public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { + public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { final var viewModel = new IssueEditView(); populate(viewModel, pathParameters, dao); @@ -521,7 +547,8 @@ return; } - final var issue = new Issue(-1); + // TODO: fix #38 - automatically select component (and version) + final var issue = new Issue(-1, projectInfo.getProject(), null); issue.setProject(projectInfo.getProject()); configureIssueEditor(viewModel, issue, dao); @@ -529,27 +556,25 @@ } @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST) - public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { + public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { try { - final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); - final var componentId = getParameter(req, Integer.class, "component"); - final Component component; - if (componentId.isPresent()) { - component = dao.getComponentDao().find(componentId.get()); - } else { - component = null; - } - final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); + final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); if (project == null) { // TODO: improve error handling, because not found is not correct for this POST request resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } - issue.setProject(project); + final var componentId = getParameter(req, Integer.class, "component"); + final Component component; + if (componentId.isPresent()) { + component = dao.findComponent(componentId.get()); + } else { + component = null; + } + final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow(), project, component); getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus); issue.setSubject(getParameter(req, String.class, "subject").orElseThrow()); - issue.setComponent(component); getParameter(req, Integer.class, "assignee").map(userid -> { if (userid >= 0) { return new User(userid); @@ -566,23 +591,23 @@ getParameter(req, Integer[].class, "affected") .map(Stream::of) .map(stream -> - stream.map(Version::new).collect(Collectors.toList()) + stream.map(id -> new Version(id, project.getId())) + .collect(Collectors.toList()) ).ifPresent(issue::setAffectedVersions); getParameter(req, Integer[].class, "resolved") .map(Stream::of) .map(stream -> - stream.map(Version::new).collect(Collectors.toList()) + stream.map(id -> new Version(id, project.getId())) + .collect(Collectors.toList()) ).ifPresent(issue::setResolvedVersions); - final var issueDao = dao.getIssueDao(); if (issue.getId() > 0) { - // TODO: use return value - issueDao.update(issue); + dao.updateIssue(issue); } else { - issueDao.save(issue, project); + dao.insertIssue(issue); } - // TODO: fix redirect location + // TODO: implement #110 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); @@ -594,19 +619,19 @@ } @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST) - public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { + public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { final var issueIdParam = getParameter(req, Integer.class, "issueid"); if (issueIdParam.isEmpty()) { resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form."); return; } - final var issue = dao.getIssueDao().find(issueIdParam.get()); + final var issue = dao.findIssue(issueIdParam.get()); if (issue == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } try { - final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1)); + final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1), issue.getId()); issueComment.setComment(getParameter(req, String.class, "comment").orElse("")); if (issueComment.getComment().isBlank()) { @@ -615,12 +640,11 @@ LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId()); if (req.getRemoteUser() != null) { - Optional.ofNullable(dao.getUserDao().findByUsername(req.getRemoteUser())).ifPresent(issueComment::setAuthor); + Optional.ofNullable(dao.findUserByName(req.getRemoteUser())).ifPresent(issueComment::setAuthor); } - dao.getIssueDao().saveComment(issue, issueComment); + dao.insertComment(issueComment); - // TODO: fix redirect location setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);