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

Wed, 25 Nov 2020 11:17:39 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 25 Nov 2020 11:17:39 +0100
changeset 161
3d9218457b62
parent 159
86b5d8a1662f
child 162
2adc8623dd89
permissions
-rw-r--r--

temporarily fixes version and component filter settings

     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.DaoProvider;
    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 static int parseIntOrZero(String str) {
    68         try {
    69             return Integer.parseInt(str);
    70         } catch (NumberFormatException ex) {
    71             return 0;
    72         }
    73     }
    75     private void populate(ProjectView viewModel, PathParameters pathParameters, DaoProvider dao) throws SQLException {
    76         final var projectDao = dao.getProjectDao();
    77         final var versionDao = dao.getVersionDao();
    78         final var componentDao = dao.getComponentDao();
    80         projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add);
    82         if (pathParameters == null)
    83             return;
    85         // Select Project
    86         final var project = projectDao.findByNode(pathParameters.get("project"));
    87         if (project == null)
    88             return;
    90         final var info = new ProjectInfo(project);
    91         info.setVersions(versionDao.list(project));
    92         info.setComponents(componentDao.list(project));
    93         info.setIssueSummary(projectDao.getIssueSummary(project));
    94         viewModel.setProjectInfo(info);
    96         // Select Version
    97         final var versionNode = pathParameters.get("version");
    98         if (versionNode != null) {
    99             if ("no-version".equals(versionNode)) {
   100                 viewModel.setVersionFilter(ProjectView.NO_VERSION);
   101             } else if ("all-versions".equals(versionNode)) {
   102                 viewModel.setVersionFilter(ProjectView.ALL_VERSIONS);
   103             } else {
   104                 viewModel.setVersionFilter(versionDao.findByNode(project, versionNode));
   105             }
   106         }
   108         // Select Component
   109         final var componentNode = pathParameters.get("component");
   110         if (componentNode != null) {
   111             if ("no-component".equals(componentNode)) {
   112                 viewModel.setComponentFilter(ProjectView.NO_COMPONENT);
   113             } else if ("all-components".equals(componentNode)) {
   114                 viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS);
   115             } else {
   116                 viewModel.setComponentFilter(componentDao.findByNode(project, componentNode));
   117             }
   118         }
   119     }
   121     private static String sanitizeNode(String node, String defaultValue) {
   122         String result = node == null || node.isBlank() ? defaultValue : node;
   123         result = result.replace('/', '-');
   124         if (result.equals(".") || result.equals("..")) {
   125             return "_"+result;
   126         } else {
   127             return result;
   128         }
   129     }
   131     private void forwardView(HttpServletRequest req, HttpServletResponse resp, ProjectView viewModel, String name) throws ServletException, IOException {
   132         setViewModel(req, viewModel);
   133         setContentPage(req, name);
   134         setStylesheet(req, "projects");
   135         setNavigationMenu(req, "project-navmenu");
   136         renderSite(req, resp);
   137     }
   139     @RequestMapping(method = HttpMethod.GET)
   140     public void index(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException {
   141         final var viewModel = new ProjectView();
   142         populate(viewModel, null, dao);
   144         final var projectDao = dao.getProjectDao();
   145         final var versionDao = dao.getVersionDao();
   147         for (var info : viewModel.getProjectList()) {
   148             info.setVersions(versionDao.list(info.getProject()));
   149             info.setIssueSummary(projectDao.getIssueSummary(info.getProject()));
   150         }
   152         forwardView(req, resp, viewModel, "projects");
   153     }
   155     private void configureProjectEditor(ProjectEditView viewModel, Project project, DaoProvider dao) throws SQLException {
   156         viewModel.setProject(project);
   157         viewModel.setUsers(dao.getUserDao().list());
   158     }
   160     @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET)
   161     public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws IOException, SQLException, ServletException {
   162         final var viewModel = new ProjectEditView();
   163         populate(viewModel, pathParams, dao);
   165         if (!viewModel.isProjectInfoPresent()) {
   166             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   167             return;
   168         }
   170         configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao);
   171         forwardView(req, resp, viewModel, "project-form");
   172     }
   174     @RequestMapping(requestPath = "create", method = HttpMethod.GET)
   175     public void create(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException {
   176         final var viewModel = new ProjectEditView();
   177         populate(viewModel, null, dao);
   178         configureProjectEditor(viewModel, new Project(-1), dao);
   179         forwardView(req, resp, viewModel, "project-form");
   180     }
   182     @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
   183     public void commit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException {
   185         try {
   186             final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
   187             project.setName(getParameter(req, String.class, "name").orElseThrow());
   189             final var node = getParameter(req, String.class, "node").orElse(null);
   190             project.setNode(sanitizeNode(node, project.getName()));
   192             getParameter(req, String.class, "description").ifPresent(project::setDescription);
   193             getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
   194             getParameter(req, Integer.class, "owner").map(
   195                     ownerId -> ownerId >= 0 ? new User(ownerId) : null
   196             ).ifPresent(project::setOwner);
   198             final var projectDao = dao.getProjectDao();
   199             if (project.getId() > 0) {
   200                 // TODO: unused return value
   201                 projectDao.update(project);
   202             } else {
   203                 projectDao.save(project);
   204             }
   206             setRedirectLocation(req, "./projects/");
   207             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   208             LOG.debug("Successfully updated project {}", project.getName());
   210             renderSite(req, resp);
   211         } catch (NoSuchElementException | IllegalArgumentException ex) {
   212             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   213             // TODO: implement - fix issue #21
   214         }
   215     }
   217     @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET)
   218     public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws SQLException, IOException, ServletException {
   219         final var viewModel = new ProjectDetailsView();
   220         populate(viewModel, pathParams, dao);
   222         if (!viewModel.isEveryFilterValid()) {
   223             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   224             return;
   225         }
   227         final var project = viewModel.getProjectInfo().getProject();
   228         final var version = viewModel.getVersionFilter();
   229         final var component = viewModel.getComponentFilter();
   231         final var issueDao = dao.getIssueDao();
   233         final List<Issue> issues;
   234         if (version.equals(ProjectView.NO_VERSION)) {
   235             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   236                 issues = issueDao.list(project, (Version) null);
   237             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   238                 issues = issueDao.list(project, null, null);
   239             } else {
   240                 issues = issueDao.list(project, component, null);
   241             }
   242         } else if (version.equals(ProjectView.ALL_VERSIONS)) {
   243             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   244                 issues = issueDao.list(project);
   245             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   246                 issues = issueDao.list(project, (Component)null);
   247             } else {
   248                 issues = issueDao.list(project, component);
   249             }
   250         } else {
   251             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   252                 issues = issueDao.list(project, version);
   253             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   254                 issues = issueDao.list(project, null, version);
   255             } else {
   256                 issues = issueDao.list(project, component, version);
   257             }
   258         }
   260         for (var issue : issues) issueDao.joinVersionInformation(issue);
   261         issues.sort(new IssueSorter(
   262                 new IssueSorter.Criteria(IssueSorter.Field.DONE, true),
   263                 new IssueSorter.Criteria(IssueSorter.Field.ETA, true),
   264                 new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false)
   265         ));
   268         viewModel.getProjectDetails().updateDetails(issues);
   269         if (version.getId() > 0)
   270             viewModel.getProjectDetails().updateVersionInfo(version);
   272         forwardView(req, resp, viewModel, "project-details");
   273     }
   275     @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET)
   276     public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   277         final var viewModel = new VersionsView();
   278         populate(viewModel, pathParameters, dao);
   280         final var projectInfo = viewModel.getProjectInfo();
   281         if (projectInfo == null) {
   282             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   283             return;
   284         }
   286         final var issueDao = dao.getIssueDao();
   287         final var issues = issueDao.list(projectInfo.getProject());
   288         for (var issue : issues) issueDao.joinVersionInformation(issue);
   289         viewModel.update(projectInfo.getVersions(), issues);
   291         forwardView(req, resp, viewModel, "versions");
   292     }
   294     @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET)
   295     public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   296         final var viewModel = new VersionEditView();
   297         populate(viewModel, pathParameters, dao);
   299         if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) {
   300             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   301             return;
   302         }
   304         viewModel.setVersion(viewModel.getVersionFilter());
   306         forwardView(req, resp, viewModel, "version-form");
   307     }
   309     @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET)
   310     public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   311         final var viewModel = new VersionEditView();
   312         populate(viewModel, pathParameters, dao);
   314         if (viewModel.getProjectInfo() == null) {
   315             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   316             return;
   317         }
   319         viewModel.setVersion(new Version(-1));
   321         forwardView(req, resp, viewModel, "version-form");
   322     }
   324     @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST)
   325     public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException {
   327         try {
   328             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   329             if (project == null) {
   330                 // TODO: improve error handling, because not found is not correct for this POST request
   331                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   332                 return;
   333             }
   334             final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
   335             version.setName(getParameter(req, String.class, "name").orElseThrow());
   337             final var node = getParameter(req, String.class, "node").orElse(null);
   338             version.setNode(sanitizeNode(node, version.getName()));
   340             getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
   341             version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
   343             final var versionDao = dao.getVersionDao();
   344             if (version.getId() > 0) {
   345                 // TODO: use return value
   346                 versionDao.update(version);
   347             } else {
   348                 versionDao.save(version, project);
   349             }
   351             setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/");
   352             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   354             renderSite(req, resp);
   355         } catch (NoSuchElementException | IllegalArgumentException ex) {
   356             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   357             // TODO: implement - fix issue #21
   358         }
   359     }
   361     @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET)
   362     public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   363         final var viewModel = new ComponentsView();
   364         populate(viewModel, pathParameters, dao);
   366         final var projectInfo = viewModel.getProjectInfo();
   367         if (projectInfo == null) {
   368             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   369             return;
   370         }
   372         final var issueDao = dao.getIssueDao();
   373         final var issues = issueDao.list(projectInfo.getProject());
   374         viewModel.update(projectInfo.getComponents(), issues);
   376         forwardView(req, resp, viewModel, "components");
   377     }
   379     @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET)
   380     public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   381         final var viewModel = new ComponentEditView();
   382         populate(viewModel, pathParameters, dao);
   384         if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) {
   385             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   386             return;
   387         }
   389         viewModel.setComponent(viewModel.getComponentFilter());
   390         viewModel.setUsers(dao.getUserDao().list());
   392         forwardView(req, resp, viewModel, "component-form");
   393     }
   395     @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET)
   396     public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   397         final var viewModel = new ComponentEditView();
   398         populate(viewModel, pathParameters, dao);
   400         if (viewModel.getProjectInfo() == null) {
   401             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   402             return;
   403         }
   405         viewModel.setComponent(new Component(-1));
   406         viewModel.setUsers(dao.getUserDao().list());
   408         forwardView(req, resp, viewModel, "component-form");
   409     }
   411     @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST)
   412     public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException {
   414         try {
   415             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   416             if (project == null) {
   417                 // TODO: improve error handling, because not found is not correct for this POST request
   418                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   419                 return;
   420             }
   421             final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow());
   422             component.setName(getParameter(req, String.class, "name").orElseThrow());
   424             final var node = getParameter(req, String.class, "node").orElse(null);
   425             component.setNode(sanitizeNode(node, component.getName()));
   427             component.setColor(getParameter(req, WebColor.class, "color").orElseThrow());
   428             getParameter(req, Integer.class, "ordinal").ifPresent(component::setOrdinal);
   429             getParameter(req, Integer.class, "lead").map(
   430                     userid -> userid >= 0 ? new User(userid) : null
   431             ).ifPresent(component::setLead);
   432             getParameter(req, String.class, "description").ifPresent(component::setDescription);
   434             final var componentDao = dao.getComponentDao();
   435             if (component.getId() > 0) {
   436                 // TODO: use return value
   437                 componentDao.update(component);
   438             } else {
   439                 componentDao.save(component, project);
   440             }
   442             setRedirectLocation(req, "./projects/" + project.getNode() + "/components/");
   443             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   445             renderSite(req, resp);
   446         } catch (NoSuchElementException | IllegalArgumentException ex) {
   447             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   448             // TODO: implement - fix issue #21
   449         }
   450     }
   452     private void configureIssueEditor(IssueEditView viewModel, Issue issue, DaoProvider dao) throws SQLException {
   453         final var project = viewModel.getProjectInfo().getProject();
   454         issue.setProject(project); // automatically set current project for new issues
   455         viewModel.setIssue(issue);
   456         viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions());
   457         viewModel.setUsers(dao.getUserDao().list());
   458         viewModel.setComponents(dao.getComponentDao().list(project));
   459     }
   461     @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET)
   462     public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   463         final var viewModel = new IssueDetailView();
   464         populate(viewModel, pathParameters, dao);
   466         final var projectInfo = viewModel.getProjectInfo();
   467         if (projectInfo == null) {
   468             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   469             return;
   470         }
   472         final var issueDao = dao.getIssueDao();
   473         final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue")));
   474         if (issue == null) {
   475             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   476             return;
   477         }
   479         issueDao.joinVersionInformation(issue);
   480         viewModel.setIssue(issue);
   481         viewModel.setComments(issueDao.listComments(issue));
   483         forwardView(req, resp, viewModel, "issue-view");
   484     }
   486     // TODO: why should the issue editor be child of $project?
   487     @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET)
   488     public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   489         final var viewModel = new IssueEditView();
   490         populate(viewModel, pathParameters, dao);
   492         final var projectInfo = viewModel.getProjectInfo();
   493         if (projectInfo == null) {
   494             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   495             return;
   496         }
   498         final var issueDao = dao.getIssueDao();
   499         final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue")));
   500         if (issue == null) {
   501             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   502             return;
   503         }
   505         issueDao.joinVersionInformation(issue);
   506         configureIssueEditor(viewModel, issue, dao);
   508         forwardView(req, resp, viewModel, "issue-form");
   509     }
   511     @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET)
   512     public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException {
   513         final var viewModel = new IssueEditView();
   514         populate(viewModel, pathParameters, dao);
   516         final var projectInfo = viewModel.getProjectInfo();
   517         if (projectInfo == null) {
   518             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   519             return;
   520         }
   522         final var issue = new Issue(-1);
   523         issue.setProject(projectInfo.getProject());
   524         configureIssueEditor(viewModel, issue, dao);
   526         forwardView(req, resp, viewModel, "issue-form");
   527     }
   529     @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST)
   530     public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException {
   531         try {
   532             final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
   533             final var componentId = getParameter(req, Integer.class, "component");
   534             final Component component;
   535             if (componentId.isPresent()) {
   536                 component = dao.getComponentDao().find(componentId.get());
   537             } else {
   538                 component = null;
   539             }
   540             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   541             if (project == null) {
   542                 // TODO: improve error handling, because not found is not correct for this POST request
   543                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   544                 return;
   545             }
   546             issue.setProject(project);
   547             getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory);
   548             getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus);
   549             issue.setSubject(getParameter(req, String.class, "subject").orElseThrow());
   550             issue.setComponent(component);
   551             getParameter(req, Integer.class, "assignee").map(userid -> {
   552                 if (userid >= 0) {
   553                     return new User(userid);
   554                 } else if (userid == -2) {
   555                     return Optional.ofNullable(component).map(Component::getLead).orElse(null);
   556                 } else {
   557                     return null;
   558                 }
   559             }
   560             ).ifPresent(issue::setAssignee);
   561             getParameter(req, String.class, "description").ifPresent(issue::setDescription);
   562             getParameter(req, Date.class, "eta").ifPresent(issue::setEta);
   564             getParameter(req, Integer[].class, "affected")
   565                     .map(Stream::of)
   566                     .map(stream ->
   567                             stream.map(Version::new).collect(Collectors.toList())
   568                     ).ifPresent(issue::setAffectedVersions);
   569             getParameter(req, Integer[].class, "resolved")
   570                     .map(Stream::of)
   571                     .map(stream ->
   572                             stream.map(Version::new).collect(Collectors.toList())
   573                     ).ifPresent(issue::setResolvedVersions);
   575             final var issueDao = dao.getIssueDao();
   576             if (issue.getId() > 0) {
   577                 // TODO: use return value
   578                 issueDao.update(issue);
   579             } else {
   580                 issueDao.save(issue, project);
   581             }
   583             // TODO: fix redirect location
   584             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   585             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   587             renderSite(req, resp);
   588         } catch (NoSuchElementException | IllegalArgumentException ex) {
   589             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   590             // TODO: implement - fix issue #21
   591         }
   592     }
   594     @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST)
   595     public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException {
   596         final var issueIdParam = getParameter(req, Integer.class, "issueid");
   597         if (issueIdParam.isEmpty()) {
   598             resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form.");
   599             return;
   600         }
   601         final var issue = dao.getIssueDao().find(issueIdParam.get());
   602         if (issue == null) {
   603             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   604             return;
   605         }
   606         try {
   607             final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1));
   608             issueComment.setComment(getParameter(req, String.class, "comment").orElse(""));
   610             if (issueComment.getComment().isBlank()) {
   611                 throw new IllegalArgumentException("comment.null");
   612             }
   614             LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId());
   615             if (req.getRemoteUser() != null) {
   616                 Optional.ofNullable(dao.getUserDao().findByUsername(req.getRemoteUser())).ifPresent(issueComment::setAuthor);
   617             }
   619             dao.getIssueDao().saveComment(issue, issueComment);
   621             // TODO: fix redirect location
   622             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   623             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   625             renderSite(req, resp);
   626         } catch (NoSuchElementException | IllegalArgumentException ex) {
   627             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   628             // TODO: implement - fix issue #21
   629         }
   630     }
   631 }

mercurial