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

Fri, 06 Nov 2020 10:50:32 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 06 Nov 2020 10:50:32 +0100
changeset 158
4f912cd42876
parent 157
1e6f16fad3a5
child 159
86b5d8a1662f
permissions
-rw-r--r--

migrates constants and removes global functions

     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 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, DataAccessObjects 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 ("no-version".equals(versionNode)) {
    99             viewModel.setVersionFilter(ProjectView.NO_VERSION);
   100         } else if ("all-versions".equals(versionNode)) {
   101             viewModel.setVersionFilter(ProjectView.ALL_VERSIONS);
   102         } else {
   103             viewModel.setVersionFilter(versionDao.findByNode(project, versionNode));
   104         }
   106         // Select Component
   107         final var componentNode = pathParameters.get("component");
   108         if ("no-component".equals(componentNode)) {
   109             viewModel.setComponentFilter(ProjectView.NO_COMPONENT);
   110         } else if ("all-components".equals(componentNode)) {
   111             viewModel.setComponentFilter(ProjectView.ALL_COMPONENTS);
   112         } else {
   113             viewModel.setComponentFilter(componentDao.findByNode(project, componentNode));
   114         }
   115     }
   117     private static String sanitizeNode(String node, String defaultValue) {
   118         String result = node == null || node.isBlank() ? defaultValue : node;
   119         result = result.replace('/', '-');
   120         if (result.equals(".") || result.equals("..")) {
   121             return "_"+result;
   122         } else {
   123             return result;
   124         }
   125     }
   127     private void forwardView(HttpServletRequest req, HttpServletResponse resp, ProjectView viewModel, String name) throws ServletException, IOException {
   128         setViewModel(req, viewModel);
   129         setContentPage(req, name);
   130         setStylesheet(req, "projects");
   131         setNavigationMenu(req, "project-navmenu");
   132         renderSite(req, resp);
   133     }
   135     @RequestMapping(method = HttpMethod.GET)
   136     public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException {
   137         final var viewModel = new ProjectView();
   138         populate(viewModel, null, dao);
   140         final var projectDao = dao.getProjectDao();
   141         final var versionDao = dao.getVersionDao();
   143         for (var info : viewModel.getProjectList()) {
   144             info.setVersions(versionDao.list(info.getProject()));
   145             info.setIssueSummary(projectDao.getIssueSummary(info.getProject()));
   146         }
   148         forwardView(req, resp, viewModel, "projects");
   149     }
   151     private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException {
   152         viewModel.setProject(project);
   153         viewModel.setUsers(dao.getUserDao().list());
   154     }
   156     @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET)
   157     public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   158         final var viewModel = new ProjectEditView();
   159         populate(viewModel, pathParams, dao);
   161         if (!viewModel.isProjectInfoPresent()) {
   162             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   163             return;
   164         }
   166         configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao);
   167         forwardView(req, resp, viewModel, "project-form");
   168     }
   170     @RequestMapping(requestPath = "create", method = HttpMethod.GET)
   171     public void create(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, ServletException, IOException {
   172         final var viewModel = new ProjectEditView();
   173         populate(viewModel, null, dao);
   174         configureProjectEditor(viewModel, new Project(-1), dao);
   175         forwardView(req, resp, viewModel, "project-form");
   176     }
   178     @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
   179     public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   181         try {
   182             final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
   183             project.setName(getParameter(req, String.class, "name").orElseThrow());
   185             final var node = getParameter(req, String.class, "node").orElse(null);
   186             project.setNode(sanitizeNode(node, project.getName()));
   188             getParameter(req, String.class, "description").ifPresent(project::setDescription);
   189             getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
   190             getParameter(req, Integer.class, "owner").map(
   191                     ownerId -> ownerId >= 0 ? new User(ownerId) : null
   192             ).ifPresent(project::setOwner);
   194             dao.getProjectDao().saveOrUpdate(project);
   196             setRedirectLocation(req, "./projects/");
   197             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   198             LOG.debug("Successfully updated project {}", project.getName());
   200             renderSite(req, resp);
   201         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   202             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   203             // TODO: implement - fix issue #21
   204         }
   205     }
   207     @RequestMapping(requestPath = "$project/$component/$version/issues/", method = HttpMethod.GET)
   208     public void issues(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException, ServletException {
   209         final var viewModel = new ProjectDetailsView();
   210         populate(viewModel, pathParams, dao);
   212         if (!viewModel.isEveryFilterValid()) {
   213             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   214             return;
   215         }
   217         final var project = viewModel.getProjectInfo().getProject();
   218         final var version = viewModel.getVersionFilter();
   219         final var component = viewModel.getComponentFilter();
   221         final var issueDao = dao.getIssueDao();
   223         final List<Issue> issues;
   224         if (version.equals(ProjectView.NO_VERSION)) {
   225             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   226                 issues = issueDao.list(project, (Version) null);
   227             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   228                 issues = issueDao.list(project, null, null);
   229             } else {
   230                 issues = issueDao.list(project, component, null);
   231             }
   232         } else if (version.equals(ProjectView.ALL_VERSIONS)) {
   233             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   234                 issues = issueDao.list(project);
   235             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   236                 issues = issueDao.list(project, (Component)null);
   237             } else {
   238                 issues = issueDao.list(project, component);
   239             }
   240         } else {
   241             if (component.equals(ProjectView.ALL_COMPONENTS)) {
   242                 issues = issueDao.list(project, version);
   243             } else if (component.equals(ProjectView.NO_COMPONENT)) {
   244                 issues = issueDao.list(project, null, version);
   245             } else {
   246                 issues = issueDao.list(project, component, version);
   247             }
   248         }
   250         for (var issue : issues) issueDao.joinVersionInformation(issue);
   251         issues.sort(new IssueSorter(
   252                 new IssueSorter.Criteria(IssueSorter.Field.DONE, true),
   253                 new IssueSorter.Criteria(IssueSorter.Field.ETA, true),
   254                 new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false)
   255         ));
   258         viewModel.getProjectDetails().updateDetails(issues);
   259         if (version.getId() > 0)
   260             viewModel.getProjectDetails().updateVersionInfo(version);
   262         forwardView(req, resp, viewModel, "project-details");
   263     }
   265     @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET)
   266     public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   267         final var viewModel = new VersionsView();
   268         populate(viewModel, pathParameters, dao);
   270         final var projectInfo = viewModel.getProjectInfo();
   271         if (projectInfo == null) {
   272             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   273             return;
   274         }
   276         final var issueDao = dao.getIssueDao();
   277         final var issues = issueDao.list(projectInfo.getProject());
   278         for (var issue : issues) issueDao.joinVersionInformation(issue);
   279         viewModel.update(projectInfo.getVersions(), issues);
   281         forwardView(req, resp, viewModel, "versions");
   282     }
   284     @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET)
   285     public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   286         final var viewModel = new VersionEditView();
   287         populate(viewModel, pathParameters, dao);
   289         if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) {
   290             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   291             return;
   292         }
   294         viewModel.setVersion(viewModel.getVersionFilter());
   296         forwardView(req, resp, viewModel, "version-form");
   297     }
   299     @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET)
   300     public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   301         final var viewModel = new VersionEditView();
   302         populate(viewModel, pathParameters, dao);
   304         if (viewModel.getProjectInfo() == null) {
   305             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   306             return;
   307         }
   309         viewModel.setVersion(new Version(-1));
   311         forwardView(req, resp, viewModel, "version-form");
   312     }
   314     @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST)
   315     public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   317         try {
   318             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   319             if (project == null) {
   320                 // TODO: improve error handling, because not found is not correct for this POST request
   321                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   322                 return;
   323             }
   324             final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
   325             version.setName(getParameter(req, String.class, "name").orElseThrow());
   327             final var node = getParameter(req, String.class, "node").orElse(null);
   328             version.setNode(sanitizeNode(node, version.getName()));
   330             getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
   331             version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
   332             dao.getVersionDao().saveOrUpdate(version, project);
   334             setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/");
   335             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   337             renderSite(req, resp);
   338         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   339             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   340             // TODO: implement - fix issue #21
   341         }
   342     }
   344     @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET)
   345     public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   346         final var viewModel = new ComponentsView();
   347         populate(viewModel, pathParameters, dao);
   349         final var projectInfo = viewModel.getProjectInfo();
   350         if (projectInfo == null) {
   351             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   352             return;
   353         }
   355         final var issueDao = dao.getIssueDao();
   356         final var issues = issueDao.list(projectInfo.getProject());
   357         viewModel.update(projectInfo.getComponents(), issues);
   359         forwardView(req, resp, viewModel, "components");
   360     }
   362     @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET)
   363     public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   364         final var viewModel = new ComponentEditView();
   365         populate(viewModel, pathParameters, dao);
   367         if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) {
   368             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   369             return;
   370         }
   372         viewModel.setComponent(viewModel.getComponentFilter());
   373         viewModel.setUsers(dao.getUserDao().list());
   375         forwardView(req, resp, viewModel, "component-form");
   376     }
   378     @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET)
   379     public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   380         final var viewModel = new ComponentEditView();
   381         populate(viewModel, pathParameters, dao);
   383         if (viewModel.getProjectInfo() == null) {
   384             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   385             return;
   386         }
   388         viewModel.setComponent(new Component(-1));
   389         viewModel.setUsers(dao.getUserDao().list());
   391         forwardView(req, resp, viewModel, "component-form");
   392     }
   394     @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST)
   395     public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   397         try {
   398             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   399             if (project == null) {
   400                 // TODO: improve error handling, because not found is not correct for this POST request
   401                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   402                 return;
   403             }
   404             final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow());
   405             component.setName(getParameter(req, String.class, "name").orElseThrow());
   407             final var node = getParameter(req, String.class, "node").orElse(null);
   408             component.setNode(sanitizeNode(node, component.getName()));
   410             component.setColor(getParameter(req, WebColor.class, "color").orElseThrow());
   411             getParameter(req, Integer.class, "ordinal").ifPresent(component::setOrdinal);
   412             getParameter(req, Integer.class, "lead").map(
   413                     userid -> userid >= 0 ? new User(userid) : null
   414             ).ifPresent(component::setLead);
   415             getParameter(req, String.class, "description").ifPresent(component::setDescription);
   417             dao.getComponentDao().saveOrUpdate(component, project);
   419             setRedirectLocation(req, "./projects/" + project.getNode() + "/components/");
   420             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   422             renderSite(req, resp);
   423         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   424             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   425             // TODO: implement - fix issue #21
   426         }
   427     }
   429     private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException {
   430         final var project = viewModel.getProjectInfo().getProject();
   431         issue.setProject(project); // automatically set current project for new issues
   432         viewModel.setIssue(issue);
   433         viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions());
   434         viewModel.setUsers(dao.getUserDao().list());
   435         viewModel.setComponents(dao.getComponentDao().list(project));
   436     }
   438     @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET)
   439     public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   440         final var viewModel = new IssueDetailView();
   441         populate(viewModel, pathParameters, dao);
   443         final var projectInfo = viewModel.getProjectInfo();
   444         if (projectInfo == null) {
   445             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   446             return;
   447         }
   449         final var issueDao = dao.getIssueDao();
   450         final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue")));
   451         if (issue == null) {
   452             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   453             return;
   454         }
   456         issueDao.joinVersionInformation(issue);
   457         viewModel.setIssue(issue);
   458         viewModel.setComments(issueDao.listComments(issue));
   460         forwardView(req, resp, viewModel, "issue-view");
   461     }
   463     // TODO: why should the issue editor be child of $project?
   464     @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET)
   465     public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   466         final var viewModel = new IssueEditView();
   467         populate(viewModel, pathParameters, dao);
   469         final var projectInfo = viewModel.getProjectInfo();
   470         if (projectInfo == null) {
   471             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   472             return;
   473         }
   475         final var issueDao = dao.getIssueDao();
   476         final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue")));
   477         if (issue == null) {
   478             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   479             return;
   480         }
   482         issueDao.joinVersionInformation(issue);
   483         configureIssueEditor(viewModel, issue, dao);
   485         forwardView(req, resp, viewModel, "issue-form");
   486     }
   488     @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET)
   489     public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException, ServletException {
   490         final var viewModel = new IssueEditView();
   491         populate(viewModel, pathParameters, dao);
   493         final var projectInfo = viewModel.getProjectInfo();
   494         if (projectInfo == null) {
   495             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   496             return;
   497         }
   499         final var issue = new Issue(-1);
   500         issue.setProject(projectInfo.getProject());
   501         configureIssueEditor(viewModel, issue, dao);
   503         forwardView(req, resp, viewModel, "issue-form");
   504     }
   506     @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST)
   507     public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, ServletException {
   508         try {
   509             final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
   510             final var componentId = getParameter(req, Integer.class, "component");
   511             final Component component;
   512             if (componentId.isPresent()) {
   513                 component = dao.getComponentDao().find(componentId.get());
   514             } else {
   515                 component = null;
   516             }
   517             final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow());
   518             if (project == null) {
   519                 // TODO: improve error handling, because not found is not correct for this POST request
   520                 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   521                 return;
   522             }
   523             issue.setProject(project);
   524             getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory);
   525             getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus);
   526             issue.setSubject(getParameter(req, String.class, "subject").orElseThrow());
   527             issue.setComponent(component);
   528             getParameter(req, Integer.class, "assignee").map(userid -> {
   529                 if (userid >= 0) {
   530                     return new User(userid);
   531                 } else if (userid == -2) {
   532                     return Optional.ofNullable(component).map(Component::getLead).orElse(null);
   533                 } else {
   534                     return null;
   535                 }
   536             }
   537             ).ifPresent(issue::setAssignee);
   538             getParameter(req, String.class, "description").ifPresent(issue::setDescription);
   539             getParameter(req, Date.class, "eta").ifPresent(issue::setEta);
   541             getParameter(req, Integer[].class, "affected")
   542                     .map(Stream::of)
   543                     .map(stream ->
   544                             stream.map(Version::new).collect(Collectors.toList())
   545                     ).ifPresent(issue::setAffectedVersions);
   546             getParameter(req, Integer[].class, "resolved")
   547                     .map(Stream::of)
   548                     .map(stream ->
   549                             stream.map(Version::new).collect(Collectors.toList())
   550                     ).ifPresent(issue::setResolvedVersions);
   552             dao.getIssueDao().saveOrUpdate(issue, issue.getProject());
   554             // TODO: fix redirect location
   555             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   556             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   558             renderSite(req, resp);
   559         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   560             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   561             // TODO: implement - fix issue #21
   562         }
   563     }
   565     @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST)
   566     public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException, ServletException {
   567         final var issueIdParam = getParameter(req, Integer.class, "issueid");
   568         if (issueIdParam.isEmpty()) {
   569             resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form.");
   570             return;
   571         }
   572         final var issue = dao.getIssueDao().find(issueIdParam.get());
   573         if (issue == null) {
   574             resp.sendError(HttpServletResponse.SC_NOT_FOUND);
   575             return;
   576         }
   577         try {
   578             final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1));
   579             issueComment.setComment(getParameter(req, String.class, "comment").orElse(""));
   581             if (issueComment.getComment().isBlank()) {
   582                 throw new IllegalArgumentException("comment.null");
   583             }
   585             LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId());
   586             if (req.getRemoteUser() != null) {
   587                 dao.getUserDao().findByUsername(req.getRemoteUser()).ifPresent(issueComment::setAuthor);
   588             }
   590             dao.getIssueDao().saveComment(issue, issueComment);
   592             // TODO: fix redirect location
   593             setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view");
   594             setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
   596             renderSite(req, resp);
   597         } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
   598             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
   599             // TODO: implement - fix issue #21
   600         }
   601     }
   602 }

mercurial