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

Thu, 05 Nov 2020 13:37:48 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 05 Nov 2020 13:37:48 +0100
changeset 157
1e6f16fad3a5
parent 152
7761c37c5e61
child 158
4f912cd42876
permissions
-rw-r--r--

removes ResponseType enum

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2018 Mike Becker. All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  *
    28  */
    29 package de.uapcore.lightpit.modules;
    32 import de.uapcore.lightpit.*;
    33 import de.uapcore.lightpit.dao.DataAccessObjects;
    34 import de.uapcore.lightpit.entities.*;
    35 import de.uapcore.lightpit.types.WebColor;
    36 import de.uapcore.lightpit.viewmodel.*;
    37 import de.uapcore.lightpit.viewmodel.util.IssueSorter;
    38 import org.slf4j.Logger;
    39 import org.slf4j.LoggerFactory;
    41 import javax.servlet.ServletException;
    42 import javax.servlet.annotation.WebServlet;
    43 import javax.servlet.http.HttpServletRequest;
    44 import javax.servlet.http.HttpServletResponse;
    45 import java.io.IOException;
    46 import java.sql.Date;
    47 import java.sql.SQLException;
    48 import java.util.List;
    49 import java.util.NoSuchElementException;
    50 import java.util.Optional;
    51 import java.util.stream.Collectors;
    52 import java.util.stream.Stream;
    54 @WebServlet(
    55         name = "ProjectsModule",
    56         urlPatterns = "/projects/*"
    57 )
    58 public final class ProjectsModule extends AbstractLightPITServlet {
    60     private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class);
    62     @Override
    63     protected String getResourceBundleName() {
    64         return "localization.projects";
    65     }
    67     private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObjects dao) throws SQLException {
    68         final var projectDao = dao.getProjectDao();
    69         final var versionDao = dao.getVersionDao();
    70         final var componentDao = dao.getComponentDao();
    72         projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add);
    74         if (pathParameters == null)
    75             return;
    77         // Select Project
    78         final var project = projectDao.findByNode(pathParameters.get("project"));
    79         if (project == null)
    80             return;
    82         final var info = new ProjectInfo(project);
    83         info.setVersions(versionDao.list(project));
    84         info.setComponents(componentDao.list(project));
    85         info.setIssueSummary(projectDao.getIssueSummary(project));
    86         viewModel.setProjectInfo(info);
    88         // Select Version
    89         final var versionNode = pathParameters.get("version");
    90         if ("no-version".equals(versionNode)) {
    91             viewModel.setVersionFilter(ProjectView.NO_VERSION);
    92         } else if ("all-versions".equals(versionNode)) {
    93             viewModel.setVersionFilter(ProjectView.ALL_VERSIONS);
    94         } else {
    95             viewModel.setVersionFilter(versionDao.findByNode(project, versionNode));
    96         }
    98         // Select Component
    99         final var componentNode = pathParameters.get("component");
   100         if ("no-component".equals(componentNode)) {
   101             viewModel.setComponentFilter(ProjectView.NO_COMPONENT);
   102         } else if ("all-components".equals(componentNode)) {
   103             viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS);
   104         } else {
   105             viewModel.setComponentFilter(componentDao.findByNode(project, componentNode));
   106         }
   107     }
   109     private static String sanitizeNode(String node, String defaultValue) {
   110         String result = node == null || node.isBlank() ? defaultValue : node;
   111         result = result.replace('/', '-');
   112         if (result.equals(".") || result.equals("..")) {
   113             return "_"+result;
   114         } else {
   115             return result;
   116         }
   117     }
   119     private void forwardView(HttpServletRequest req, HttpServletResponse resp, ProjectView viewModel, String name) throws ServletException, IOException {
   120         setViewModel(req, viewModel);
   121         setContentPage(req, name);
   122         setStylesheet(req, "projects");
   123         setNavigationMenu(req, "project-navmenu");
   124         renderSite(req, resp);
   125     }
   127     @RequestMapping(method = HttpMethod.GET)
   128     public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException {
   129         final var viewModel = new ProjectView();
   130         populate(viewModel, null, dao);
   132         final var projectDao = dao.getProjectDao();
   133         final var versionDao = dao.getVersionDao();
   135         for (var info : viewModel.getProjectList()) {
   136             info.setVersions(versionDao.list(info.getProject()));
   137             info.setIssueSummary(projectDao.getIssueSummary(info.getProject()));
   138         }
   140         forwardView(req, resp, viewModel, "projects");
   141     }
   143     private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException {
   144         viewModel.setProject(project);
   145         viewModel.setUsers(dao.getUserDao().list());
   146     }
   148     @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET)
   149     public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   150         final var viewModel = new ProjectEditView();
   151         populate(viewModel, pathParams, dao);
   153         if (!viewModel.isProjectInfoPresent()) {
   154             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   155             return;
   156         }
   158         configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao);
   159         forwardView(req, resp, viewModel, "project-form");
   160     }
   162     @RequestMapping(requestPath = "create", method = HttpMethod.GET)
   163     public void create(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException {
   164         final var viewModel = new ProjectEditView();
   165         populate(viewModel, null, dao);
   166         configureProjectEditor(viewModel, new Project(-1), dao);
   167         forwardView(req, resp, viewModel, "project-form");
   168     }
   170     @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
   171     public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   173         try {
   174             final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
   175             project.setName(getParameter(req, String.class, "name").orElseThrow());
   177             final var node = getParameter(req, String.class, "node").orElse(null);
   178             project.setNode(sanitizeNode(node, project.getName()));
   180             getParameter(req, String.class, "description").ifPresent(project::setDescription);
   181             getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
   182             getParameter(req, Integer.class, "owner").map(
   183                     ownerId -> ownerId >= 0 ? new User(ownerId) : null
   184             ).ifPresent(project::setOwner);
   186             dao.getProjectDao().saveOrUpdate(project);
   188             setRedirectLocation(req, "./projects/");
   189             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   190             LOG.debug("Successfully updated project {}", project.getName());
   192             renderSite(req, resp);
   193         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   194             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   195             // TODO: implement - fix issue #21
   196         }
   197     }
   199     @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET)
   200     public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException, ServletException {
   201         final var viewModel = new ProjectDetailsView();
   202         populate(viewModel, pathParams, dao);
   204         if (!viewModel.isEveryFilterValid()) {
   205             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   206             return;
   207         }
   209         final var project = viewModel.getProjectInfo().getProject();
   210         final var version = viewModel.getVersionFilter();
   211         final var component = viewModel.getComponentFilter();
   213         final var issueDao = dao.getIssueDao();
   215         final List<Issue> issues;
   216         if (version.equals(ProjectView.NO_VERSION)) {
   217             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   218                 issues = issueDao.list(project, (Version) null);
   219             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   220                 issues = issueDao.list(project, null, null);
   221             } else {
   222                 issues = issueDao.list(project, component, null);
   223             }
   224         } else if (version.equals(ProjectView.ALL_VERSIONS)) {
   225             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   226                 issues = issueDao.list(project);
   227             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   228                 issues = issueDao.list(project, (Component)null);
   229             } else {
   230                 issues = issueDao.list(project, component);
   231             }
   232         } else {
   233             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   234                 issues = issueDao.list(project, version);
   235             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   236                 issues = issueDao.list(project, null, version);
   237             } else {
   238                 issues = issueDao.list(project, component, version);
   239             }
   240         }
   242         for (var issue : issues) issueDao.joinVersionInformation(issue);
   243         issues.sort(new IssueSorter(
   244                 new IssueSorter.Criteria(IssueSorter.Field.DONE, true),
   245                 new IssueSorter.Criteria(IssueSorter.Field.ETA, true),
   246                 new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false)
   247         ));
   250         viewModel.getProjectDetails().updateDetails(issues);
   251         if (version.getId() > 0)
   252             viewModel.getProjectDetails().updateVersionInfo(version);
   254         forwardView(req, resp, viewModel, "project-details");
   255     }
   257     @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET)
   258     public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   259         final var viewModel = new VersionsView();
   260         populate(viewModel, pathParameters, dao);
   262         final var projectInfo = viewModel.getProjectInfo();
   263         if (projectInfo == null) {
   264             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   265             return;
   266         }
   268         final var issueDao = dao.getIssueDao();
   269         final var issues = issueDao.list(projectInfo.getProject());
   270         for (var issue : issues) issueDao.joinVersionInformation(issue);
   271         viewModel.update(projectInfo.getVersions(), issues);
   273         forwardView(req, resp, viewModel, "versions");
   274     }
   276     @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET)
   277     public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   278         final var viewModel = new VersionEditView();
   279         populate(viewModel, pathParameters, dao);
   281         if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) {
   282             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   283             return;
   284         }
   286         viewModel.setVersion(viewModel.getVersionFilter());
   288         forwardView(req, resp, viewModel, "version-form");
   289     }
   291     @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET)
   292     public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   293         final var viewModel = new VersionEditView();
   294         populate(viewModel, pathParameters, dao);
   296         if (viewModel.getProjectInfo() == null) {
   297             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   298             return;
   299         }
   301         viewModel.setVersion(new Version(-1));
   303         forwardView(req, resp, viewModel, "version-form");
   304     }
   306     @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST)
   307     public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   309         try {
   310             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   311             if (project == null) {
   312                 // TODO: improve error handling, because not found is not correct for this POST request
   313                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   314                 return;
   315             }
   316             final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
   317             version.setName(getParameter(req, String.class, "name").orElseThrow());
   319             final var node = getParameter(req, String.class, "node").orElse(null);
   320             version.setNode(sanitizeNode(node, version.getName()));
   322             getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
   323             version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
   324             dao.getVersionDao().saveOrUpdate(version, project);
   326             setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/");
   327             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   329             renderSite(req, resp);
   330         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   331             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   332             // TODO: implement - fix issue #21
   333         }
   334     }
   336     @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET)
   337     public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   338         final var viewModel = new ComponentsView();
   339         populate(viewModel, pathParameters, dao);
   341         final var projectInfo = viewModel.getProjectInfo();
   342         if (projectInfo == null) {
   343             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   344             return;
   345         }
   347         final var issueDao = dao.getIssueDao();
   348         final var issues = issueDao.list(projectInfo.getProject());
   349         viewModel.update(projectInfo.getComponents(), issues);
   351         forwardView(req, resp, viewModel, "components");
   352     }
   354     @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET)
   355     public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   356         final var viewModel = new ComponentEditView();
   357         populate(viewModel, pathParameters, dao);
   359         if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) {
   360             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   361             return;
   362         }
   364         viewModel.setComponent(viewModel.getComponentFilter());
   365         viewModel.setUsers(dao.getUserDao().list());
   367         forwardView(req, resp, viewModel, "component-form");
   368     }
   370     @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET)
   371     public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   372         final var viewModel = new ComponentEditView();
   373         populate(viewModel, pathParameters, dao);
   375         if (viewModel.getProjectInfo() == null) {
   376             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   377             return;
   378         }
   380         viewModel.setComponent(new Component(-1));
   381         viewModel.setUsers(dao.getUserDao().list());
   383         forwardView(req, resp, viewModel, "component-form");
   384     }
   386     @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST)
   387     public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   389         try {
   390             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   391             if (project == null) {
   392                 // TODO: improve error handling, because not found is not correct for this POST request
   393                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   394                 return;
   395             }
   396             final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow());
   397             component.setName(getParameter(req, String.class, "name").orElseThrow());
   399             final var node = getParameter(req, String.class, "node").orElse(null);
   400             component.setNode(sanitizeNode(node, component.getName()));
   402             component.setColor(getParameter(req, WebColor.class, "color").orElseThrow());
   403             getParameter(req, Integer.class, "ordinal").ifPresent(component::setOrdinal);
   404             getParameter(req, Integer.class, "lead").map(
   405                     userid -> userid >= 0 ? new User(userid) : null
   406             ).ifPresent(component::setLead);
   407             getParameter(req, String.class, "description").ifPresent(component::setDescription);
   409             dao.getComponentDao().saveOrUpdate(component, project);
   411             setRedirectLocation(req, "./projects/" + project.getNode() + "/components/");
   412             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   414             renderSite(req, resp);
   415         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   416             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   417             // TODO: implement - fix issue #21
   418         }
   419     }
   421     private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException {
   422         final var project = viewModel.getProjectInfo().getProject();
   423         issue.setProject(project); // automatically set current project for new issues
   424         viewModel.setIssue(issue);
   425         viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions());
   426         viewModel.setUsers(dao.getUserDao().list());
   427         viewModel.setComponents(dao.getComponentDao().list(project));
   428     }
   430     @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET)
   431     public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   432         final var viewModel = new IssueDetailView();
   433         populate(viewModel, pathParameters, dao);
   435         final var projectInfo = viewModel.getProjectInfo();
   436         if (projectInfo == null) {
   437             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   438             return;
   439         }
   441         final var issueDao = dao.getIssueDao();
   442         final var issue = issueDao.find(Functions.parseIntOrZero(pathParameters.get("issue")));
   443         if (issue == null) {
   444             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   445             return;
   446         }
   448         issueDao.joinVersionInformation(issue);
   449         viewModel.setIssue(issue);
   450         viewModel.setComments(issueDao.listComments(issue));
   452         forwardView(req, resp, viewModel, "issue-view");
   453     }
   455     // TODO: why should the issue editor be child of $project?
   456     @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET)
   457     public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   458         final var viewModel = new IssueEditView();
   459         populate(viewModel, pathParameters, dao);
   461         final var projectInfo = viewModel.getProjectInfo();
   462         if (projectInfo == null) {
   463             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   464             return;
   465         }
   467         final var issueDao = dao.getIssueDao();
   468         final var issue = issueDao.find(Functions.parseIntOrZero(pathParameters.get("issue")));
   469         if (issue == null) {
   470             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   471             return;
   472         }
   474         issueDao.joinVersionInformation(issue);
   475         configureIssueEditor(viewModel, issue, dao);
   477         forwardView(req, resp, viewModel, "issue-form");
   478     }
   480     @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET)
   481     public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   482         final var viewModel = new IssueEditView();
   483         populate(viewModel, pathParameters, dao);
   485         final var projectInfo = viewModel.getProjectInfo();
   486         if (projectInfo == null) {
   487             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   488             return;
   489         }
   491         final var issue = new Issue(-1);
   492         issue.setProject(projectInfo.getProject());
   493         configureIssueEditor(viewModel, issue, dao);
   495         forwardView(req, resp, viewModel, "issue-form");
   496     }
   498     @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST)
   499     public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   500         try {
   501             final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
   502             final var componentId = getParameter(req, Integer.class, "component");
   503             final Component component;
   504             if (componentId.isPresent()) {
   505                 component = dao.getComponentDao().find(componentId.get());
   506             } else {
   507                 component = null;
   508             }
   509             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   510             if (project == null) {
   511                 // TODO: improve error handling, because not found is not correct for this POST request
   512                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   513                 return;
   514             }
   515             issue.setProject(project);
   516             getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory);
   517             getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus);
   518             issue.setSubject(getParameter(req, String.class, "subject").orElseThrow());
   519             issue.setComponent(component);
   520             getParameter(req, Integer.class, "assignee").map(userid -> {
   521                 if (userid >= 0) {
   522                     return new User(userid);
   523                 } else if (userid == -2) {
   524                     return Optional.ofNullable(component).map(Component::getLead).orElse(null);
   525                 } else {
   526                     return null;
   527                 }
   528             }
   529             ).ifPresent(issue::setAssignee);
   530             getParameter(req, String.class, "description").ifPresent(issue::setDescription);
   531             getParameter(req, Date.class, "eta").ifPresent(issue::setEta);
   533             getParameter(req, Integer[].class, "affected")
   534                     .map(Stream::of)
   535                     .map(stream ->
   536                             stream.map(Version::new).collect(Collectors.toList())
   537                     ).ifPresent(issue::setAffectedVersions);
   538             getParameter(req, Integer[].class, "resolved")
   539                     .map(Stream::of)
   540                     .map(stream ->
   541                             stream.map(Version::new).collect(Collectors.toList())
   542                     ).ifPresent(issue::setResolvedVersions);
   544             dao.getIssueDao().saveOrUpdate(issue, issue.getProject());
   546             // TODO: fix redirect location
   547             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   548             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   550             renderSite(req, resp);
   551         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   552             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   553             // TODO: implement - fix issue #21
   554         }
   555     }
   557     @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST)
   558     public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException, ServletException {
   559         final var issueIdParam = getParameter(req, Integer.class, "issueid");
   560         if (issueIdParam.isEmpty()) {
   561             resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form.");
   562             return;
   563         }
   564         final var issue = dao.getIssueDao().find(issueIdParam.get());
   565         if (issue == null) {
   566             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   567             return;
   568         }
   569         try {
   570             final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1));
   571             issueComment.setComment(getParameter(req, String.class, "comment").orElse(""));
   573             if (issueComment.getComment().isBlank()) {
   574                 throw new IllegalArgumentException("comment.null");
   575             }
   577             LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId());
   578             if (req.getRemoteUser() != null) {
   579                 dao.getUserDao().findByUsername(req.getRemoteUser()).ifPresent(issueComment::setAuthor);
   580             }
   582             dao.getIssueDao().saveComment(issue, issueComment);
   584             // TODO: fix redirect location
   585             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   586             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   588             renderSite(req, resp);
   589         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   590             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   591             // TODO: implement - fix issue #21
   592         }
   593     }
   594 }

mercurial