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

Sat, 22 Aug 2020 18:17:06 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 22 Aug 2020 18:17:06 +0200
changeset 97
602f75801644
parent 96
b7b685f31e39
child 99
a369fb1b3aa2
permissions
-rw-r--r--

first part of navigation redesign

universe@41 1 /*
universe@41 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@41 3 *
universe@41 4 * Copyright 2018 Mike Becker. All rights reserved.
universe@41 5 *
universe@41 6 * Redistribution and use in source and binary forms, with or without
universe@41 7 * modification, are permitted provided that the following conditions are met:
universe@41 8 *
universe@41 9 * 1. Redistributions of source code must retain the above copyright
universe@41 10 * notice, this list of conditions and the following disclaimer.
universe@41 11 *
universe@41 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@41 13 * notice, this list of conditions and the following disclaimer in the
universe@41 14 * documentation and/or other materials provided with the distribution.
universe@41 15 *
universe@41 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@41 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@41 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@41 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@41 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@41 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@41 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@41 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@41 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@41 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@41 26 * POSSIBILITY OF SUCH DAMAGE.
universe@41 27 *
universe@41 28 */
universe@41 29 package de.uapcore.lightpit.modules;
universe@41 30
universe@41 31
universe@41 32 import de.uapcore.lightpit.*;
universe@41 33 import de.uapcore.lightpit.dao.DataAccessObjects;
universe@64 34 import de.uapcore.lightpit.entities.*;
universe@86 35 import de.uapcore.lightpit.viewmodel.*;
universe@59 36 import org.slf4j.Logger;
universe@59 37 import org.slf4j.LoggerFactory;
universe@41 38
universe@41 39 import javax.servlet.annotation.WebServlet;
universe@41 40 import javax.servlet.http.HttpServletRequest;
universe@59 41 import javax.servlet.http.HttpServletResponse;
universe@75 42 import javax.servlet.http.HttpSession;
universe@59 43 import java.io.IOException;
universe@75 44 import java.sql.Date;
universe@47 45 import java.sql.SQLException;
universe@86 46 import java.util.ArrayList;
universe@86 47 import java.util.List;
universe@86 48 import java.util.NoSuchElementException;
universe@86 49 import java.util.Objects;
universe@83 50 import java.util.stream.Collectors;
universe@83 51 import java.util.stream.Stream;
universe@41 52
universe@52 53 import static de.uapcore.lightpit.Functions.fqn;
universe@52 54
universe@41 55 @WebServlet(
universe@41 56 name = "ProjectsModule",
universe@41 57 urlPatterns = "/projects/*"
universe@41 58 )
universe@41 59 public final class ProjectsModule extends AbstractLightPITServlet {
universe@41 60
universe@59 61 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class);
universe@59 62
universe@80 63 public static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project");
universe@80 64 public static final String SESSION_ATTR_SELECTED_ISSUE = fqn(ProjectsModule.class, "selected_issue");
universe@80 65 public static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version");
universe@52 66
universe@97 67 // TODO: try to get rid of this shit
universe@75 68 private class SessionSelection {
universe@75 69 final HttpSession session;
universe@86 70 final HttpServletRequest req;
universe@86 71 final DataAccessObjects dao;
universe@75 72 Project project;
universe@75 73 Version version;
universe@75 74 Issue issue;
universe@75 75
universe@86 76 SessionSelection(HttpServletRequest req, DataAccessObjects dao) {
universe@86 77 this.req = req;
universe@86 78 this.dao = dao;
universe@86 79 session = req.getSession();
universe@86 80 }
universe@86 81
universe@86 82 void newProject() {
universe@86 83 project = null;
universe@75 84 version = null;
universe@75 85 issue = null;
universe@75 86 updateAttributes();
universe@86 87 project = new Project(-1);
universe@86 88 updateAttributes();
universe@64 89 }
universe@75 90
universe@86 91 void newVersion() throws SQLException {
universe@86 92 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
universe@86 93 syncProject();
universe@86 94 version = null;
universe@86 95 issue = null;
universe@86 96 updateAttributes();
universe@86 97 version = new Version(-1);
universe@86 98 version.setProject(project);
universe@86 99 updateAttributes();
universe@86 100 }
universe@86 101
universe@86 102 void newIssue() throws SQLException {
universe@86 103 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
universe@86 104 syncProject();
universe@86 105 version = null;
universe@86 106 issue = null;
universe@86 107 updateAttributes();
universe@86 108 issue = new Issue(-1);
universe@86 109 issue.setProject(project);
universe@86 110 updateAttributes();
universe@86 111 }
universe@86 112
universe@86 113 void selectVersion(Version selectedVersion) throws SQLException {
universe@86 114 issue = null;
universe@86 115 version = selectedVersion;
universe@86 116 if (!version.getProject().equals(project)) {
universe@86 117 project = dao.getProjectDao().find(version.getProject().getId());
universe@75 118 }
universe@86 119 // our object contains more details
universe@86 120 version.setProject(project);
universe@86 121 updateAttributes();
universe@86 122 }
universe@86 123
universe@86 124 void selectIssue(Issue selectedIssue) throws SQLException {
universe@86 125 issue = selectedIssue;
universe@86 126 if (!issue.getProject().equals(project)) {
universe@86 127 project = dao.getProjectDao().find(issue.getProject().getId());
universe@75 128 }
universe@86 129 // our object contains more details
universe@86 130 issue.setProject(project);
universe@88 131 if (!issue.getResolvedVersions().contains(version)
universe@86 132 && !issue.getAffectedVersions().contains(version)) {
universe@86 133 version = null;
universe@86 134 }
universe@86 135 updateAttributes();
universe@86 136 }
universe@75 137
universe@86 138 void syncProject() throws SQLException {
universe@75 139 final var projectSelection = getParameter(req, Integer.class, "pid");
universe@75 140 if (projectSelection.isPresent()) {
universe@86 141 final var selectedProject = dao.getProjectDao().find(projectSelection.get());
universe@75 142 if (!Objects.equals(selectedProject, project)) {
universe@75 143 // reset version and issue if project changed
universe@75 144 version = null;
universe@75 145 issue = null;
universe@75 146 }
universe@75 147 project = selectedProject;
universe@75 148 } else {
universe@86 149 project = project == null ? null : dao.getProjectDao().find(project.getId());
universe@75 150 }
universe@86 151 }
universe@86 152
universe@86 153 void syncVersion() throws SQLException {
universe@86 154 final var versionSelection = getParameter(req, Integer.class, "vid");
universe@86 155 if (versionSelection.isPresent()) {
universe@86 156 if (versionSelection.get() < 0) {
universe@86 157 version = null;
universe@86 158 } else {
universe@86 159 final var selectedVersion = dao.getVersionDao().find(versionSelection.get());
universe@86 160 if (!Objects.equals(selectedVersion, version)) {
universe@86 161 issue = null;
universe@86 162 }
universe@86 163 selectVersion(selectedVersion);
universe@86 164 }
universe@86 165 } else {
universe@86 166 version = version == null ? null : dao.getVersionDao().find(version.getId());
universe@86 167 }
universe@86 168 }
universe@86 169
universe@86 170 void syncIssue() throws SQLException {
universe@86 171 final var issueSelection = getParameter(req, Integer.class, "issue");
universe@86 172 if (issueSelection.isPresent()) {
universe@97 173 if (issueSelection.get() < 0) {
universe@97 174 issue = null;
universe@97 175 } else {
universe@97 176 final var selectedIssue = dao.getIssueDao().find(issueSelection.get());
universe@97 177 dao.getIssueDao().joinVersionInformation(selectedIssue);
universe@97 178 selectIssue(selectedIssue);
universe@97 179 }
universe@86 180 } else {
universe@86 181 issue = issue == null ? null : dao.getIssueDao().find(issue.getId());
universe@86 182 }
universe@86 183 }
universe@86 184
universe@86 185 void sync() throws SQLException {
universe@86 186 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT);
universe@86 187 version = (Version) session.getAttribute(SESSION_ATTR_SELECTED_VERSION);
universe@86 188 issue = (Issue) session.getAttribute(SESSION_ATTR_SELECTED_ISSUE);
universe@86 189
universe@86 190 syncProject();
universe@86 191 syncVersion();
universe@86 192 syncIssue();
universe@86 193
universe@75 194 updateAttributes();
universe@75 195 }
universe@75 196
universe@86 197 private void updateAttributes() {
universe@75 198 session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, project);
universe@75 199 session.setAttribute(SESSION_ATTR_SELECTED_VERSION, version);
universe@75 200 session.setAttribute(SESSION_ATTR_SELECTED_ISSUE, issue);
universe@75 201 }
universe@71 202 }
universe@71 203
universe@78 204 @Override
universe@78 205 protected String getResourceBundleName() {
universe@78 206 return "localization.projects";
universe@78 207 }
universe@71 208
universe@97 209 private String queryParams(Project p, Version v, Issue i) {
universe@97 210 return String.format("pid=%d&vid=%d&issue=%d",
universe@97 211 p == null ? -1 : p.getId(),
universe@97 212 v == null ? -1 : v.getId(),
universe@97 213 i == null ? -1 : i.getId()
universe@97 214 );
universe@97 215 }
universe@80 216
universe@71 217 /**
universe@96 218 * Creates the navigation menu.
universe@71 219 *
universe@97 220 * @param projects the list of projects
universe@86 221 * @param selection the currently selected objects
universe@97 222 * @param projInfo info about the currently selected project or null
universe@96 223 * @return a dynamic navigation menu trying to display as many levels as possible
universe@71 224 */
universe@97 225 private List<MenuEntry> getNavMenu(List<Project> projects, SessionSelection selection, ProjectInfo projInfo) {
universe@97 226 final var navigation = new ArrayList<MenuEntry>();
universe@71 227
universe@97 228 for (Project proj : projects) {
universe@97 229 final var projEntry = new MenuEntry(
universe@97 230 proj.getName(),
universe@97 231 "projects/view?pid=" + proj.getId()
universe@97 232 );
universe@97 233 navigation.add(projEntry);
universe@97 234 if (proj.equals(selection.project)) {
universe@97 235 projEntry.setActive(true);
universe@71 236
universe@97 237 // ****************
universe@97 238 // Versions Section
universe@97 239 // ****************
universe@97 240 {
universe@97 241 final var entry = new MenuEntry(1,
universe@97 242 new ResourceKey("localization.projects", "menu.versions"),
universe@97 243 "projects/view?" + queryParams(proj, null, null)
universe@97 244 );
universe@97 245 navigation.add(entry);
universe@97 246 }
universe@97 247
universe@97 248 final var level2 = new ArrayList<MenuEntry>();
universe@97 249 {
universe@97 250 final var entry = new MenuEntry(
universe@97 251 new ResourceKey("localization.projects", "filter.all"),
universe@97 252 "projects/view?" + queryParams(proj, null, null)
universe@97 253 );
universe@97 254 if (selection.version == null) entry.setActive(true);
universe@97 255 level2.add(entry);
universe@97 256 }
universe@97 257
universe@97 258 for (Version version : projInfo.getVersions()) {
universe@97 259 final var entry = new MenuEntry(
universe@97 260 version.getName(),
universe@97 261 "projects/versions/view?" + queryParams(proj, version, null)
universe@97 262 );
universe@97 263 if (version.equals(selection.version)) entry.setActive(true);
universe@97 264 level2.add(entry);
universe@97 265 }
universe@97 266
universe@97 267 level2.forEach(e -> e.setLevel(2));
universe@97 268 navigation.addAll(level2);
universe@75 269 }
universe@75 270 }
universe@75 271
universe@96 272 return navigation;
universe@64 273 }
universe@64 274
universe@61 275 @RequestMapping(method = HttpMethod.GET)
universe@47 276 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
universe@75 277 final var sessionSelection = new SessionSelection(req, dao);
universe@86 278 sessionSelection.sync();
universe@86 279
universe@86 280 final var projectDao = dao.getProjectDao();
universe@86 281 final var versionDao = dao.getVersionDao();
universe@86 282
universe@86 283 final var projectList = projectDao.list();
universe@86 284
universe@86 285 final var viewModel = new ProjectIndexView();
universe@86 286 for (var project : projectList) {
universe@86 287 final var info = new ProjectInfo(project);
universe@86 288 info.setVersions(versionDao.list(project));
universe@86 289 info.setIssueSummary(projectDao.getIssueSummary(project));
universe@86 290 viewModel.getProjects().add(info);
universe@86 291 }
universe@86 292
universe@86 293 setViewModel(req, viewModel);
universe@74 294 setContentPage(req, "projects");
universe@52 295 setStylesheet(req, "projects");
universe@52 296
universe@97 297 setNavigationMenu(req, getNavMenu(projectList, sessionSelection, currentProjectInfo(dao, sessionSelection.project)));
universe@45 298
universe@45 299 return ResponseType.HTML;
universe@45 300 }
universe@45 301
universe@97 302 private ProjectInfo currentProjectInfo(DataAccessObjects dao, Project project) throws SQLException {
universe@97 303 if (project == null) return null;
universe@97 304 final var projectDao = dao.getProjectDao();
universe@97 305 final var versionDao = dao.getVersionDao();
universe@97 306
universe@97 307 final var info = new ProjectInfo(project);
universe@97 308 info.setVersions(versionDao.list(project));
universe@97 309 info.setIssueSummary(projectDao.getIssueSummary(project));
universe@97 310 return info;
universe@97 311 }
universe@97 312
universe@86 313 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
universe@86 314 final var viewModel = new ProjectEditView();
universe@86 315 viewModel.setProject(selection.project);
universe@86 316 viewModel.setUsers(dao.getUserDao().list());
universe@97 317 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
universe@86 318 setViewModel(req, viewModel);
universe@74 319 setContentPage(req, "project-form");
universe@86 320 return viewModel;
universe@71 321 }
universe@71 322
universe@47 323 @RequestMapping(requestPath = "edit", method = HttpMethod.GET)
universe@51 324 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
universe@86 325 final var selection = new SessionSelection(req, dao);
universe@86 326 if (getParameter(req, Integer.class, "pid").isEmpty()) {
universe@86 327 selection.newProject();
universe@86 328 } else {
universe@86 329 selection.sync();
universe@86 330 }
universe@47 331
universe@75 332 configureEditForm(req, dao, selection);
universe@47 333
universe@47 334 return ResponseType.HTML;
universe@47 335 }
universe@47 336
universe@47 337 @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
universe@68 338 public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
universe@47 339
universe@75 340 Project project = new Project(-1);
universe@47 341 try {
universe@47 342 project = new Project(getParameter(req, Integer.class, "id").orElseThrow());
universe@47 343 project.setName(getParameter(req, String.class, "name").orElseThrow());
universe@47 344 getParameter(req, String.class, "description").ifPresent(project::setDescription);
universe@47 345 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
universe@47 346 getParameter(req, Integer.class, "owner").map(
universe@47 347 ownerId -> ownerId >= 0 ? new User(ownerId) : null
universe@47 348 ).ifPresent(project::setOwner);
universe@47 349
universe@47 350 dao.getProjectDao().saveOrUpdate(project);
universe@47 351
universe@70 352 setRedirectLocation(req, "./projects/");
universe@74 353 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
universe@59 354 LOG.debug("Successfully updated project {}", project.getName());
universe@75 355 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
universe@59 356 LOG.warn("Form validation failure: {}", ex.getMessage());
universe@59 357 LOG.debug("Details:", ex);
universe@86 358 final var selection = new SessionSelection(req, dao);
universe@86 359 selection.project = project;
universe@86 360 final var vm = configureEditForm(req, dao, selection);
universe@86 361 vm.setErrorText(ex.getMessage()); // TODO: error text
universe@47 362 }
universe@47 363
universe@47 364 return ResponseType.HTML;
universe@47 365 }
universe@47 366
universe@70 367 @RequestMapping(requestPath = "view", method = HttpMethod.GET)
universe@80 368 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
universe@86 369 final var selection = new SessionSelection(req, dao);
universe@86 370 selection.sync();
universe@86 371
universe@86 372 if (selection.project == null) {
universe@80 373 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected.");
universe@80 374 return ResponseType.NONE;
universe@80 375 }
universe@47 376
universe@97 377 final var projectDao = dao.getProjectDao();
universe@80 378 final var versionDao = dao.getVersionDao();
universe@86 379 final var issueDao = dao.getIssueDao();
universe@70 380
universe@86 381 final var viewModel = new ProjectView(selection.project);
universe@86 382 final var issues = issueDao.list(selection.project);
universe@86 383 for (var issue : issues) issueDao.joinVersionInformation(issue);
universe@86 384 viewModel.setIssues(issues);
universe@97 385 // TODO: fix duplicated selection of versions (projectInfo also contains these infos)
universe@86 386 viewModel.setVersions(versionDao.list(selection.project));
universe@86 387 viewModel.updateVersionInfo();
universe@86 388 setViewModel(req, viewModel);
universe@80 389
universe@97 390 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
universe@74 391 setContentPage(req, "project-details");
universe@80 392 setStylesheet(req, "projects");
universe@59 393
universe@59 394 return ResponseType.HTML;
universe@59 395 }
universe@59 396
universe@86 397 @RequestMapping(requestPath = "versions/view", method = HttpMethod.GET)
universe@86 398 public ResponseType viewVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
universe@86 399 final var selection = new SessionSelection(req, dao);
universe@86 400 selection.sync();
universe@86 401 if (selection.version == null) {
universe@86 402 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
universe@86 403 return ResponseType.NONE;
universe@86 404 }
universe@71 405
universe@97 406 final var projectDao = dao.getProjectDao();
universe@86 407 final var issueDao = dao.getIssueDao();
universe@97 408
universe@86 409 final var viewModel = new VersionView(selection.version);
universe@86 410 final var issues = issueDao.list(selection.version);
universe@86 411 for (var issue : issues) issueDao.joinVersionInformation(issue);
universe@86 412 viewModel.setIssues(issues);
universe@86 413 setViewModel(req, viewModel);
universe@80 414
universe@97 415 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
universe@86 416 setContentPage(req, "version");
universe@86 417 setStylesheet(req, "projects");
universe@86 418
universe@86 419 return ResponseType.HTML;
universe@86 420 }
universe@86 421
universe@86 422 private VersionEditView configureEditVersionForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
universe@86 423 final var viewModel = new VersionEditView(selection.version);
universe@86 424 if (selection.version.getProject() == null) {
universe@86 425 viewModel.setProjects(dao.getProjectDao().list());
universe@86 426 }
universe@86 427 setViewModel(req, viewModel);
universe@74 428 setContentPage(req, "version-form");
universe@97 429 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
universe@86 430 return viewModel;
universe@71 431 }
universe@71 432
universe@59 433 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET)
universe@86 434 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
universe@86 435 final var selection = new SessionSelection(req, dao);
universe@86 436 if (getParameter(req, Integer.class, "vid").isEmpty()) {
universe@86 437 selection.newVersion();
universe@86 438 } else {
universe@86 439 selection.sync();
universe@86 440 }
universe@59 441
universe@86 442 configureEditVersionForm(req, dao, selection);
universe@59 443
universe@59 444 return ResponseType.HTML;
universe@59 445 }
universe@59 446
universe@59 447 @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST)
universe@80 448 public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException {
universe@59 449
universe@86 450 var version = new Version(-1);
universe@59 451 try {
universe@86 452 version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
universe@86 453 version.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow()));
universe@59 454 version.setName(getParameter(req, String.class, "name").orElseThrow());
universe@59 455 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
universe@59 456 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
universe@59 457 dao.getVersionDao().saveOrUpdate(version);
universe@59 458
universe@75 459 // specifying the pid parameter will purposely reset the session selected version!
universe@96 460 setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId());
universe@74 461 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
universe@75 462 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
universe@59 463 LOG.warn("Form validation failure: {}", ex.getMessage());
universe@59 464 LOG.debug("Details:", ex);
universe@86 465 final var selection = new SessionSelection(req, dao);
universe@86 466 selection.selectVersion(version);
universe@86 467 final var viewModel = configureEditVersionForm(req, dao, selection);
universe@86 468 // TODO: set Error Text
universe@59 469 }
universe@41 470
universe@43 471 return ResponseType.HTML;
universe@41 472 }
universe@64 473
universe@86 474 private IssueEditView configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException {
universe@86 475 final var viewModel = new IssueEditView(selection.issue);
universe@83 476
universe@86 477 if (selection.issue.getProject() == null) {
universe@86 478 viewModel.setProjects(dao.getProjectDao().list());
universe@83 479 } else {
universe@86 480 viewModel.setVersions(dao.getVersionDao().list(selection.issue.getProject()));
universe@83 481 }
universe@86 482 viewModel.setUsers(dao.getUserDao().list());
universe@86 483 setViewModel(req, viewModel);
universe@71 484
universe@74 485 setContentPage(req, "issue-form");
universe@97 486 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project)));
universe@86 487 return viewModel;
universe@80 488 }
universe@80 489
universe@80 490 @RequestMapping(requestPath = "issues/", method = HttpMethod.GET)
universe@80 491 public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
universe@86 492 final var selection = new SessionSelection(req, dao);
universe@86 493 selection.sync();
universe@86 494 if (selection.project == null) {
universe@80 495 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected.");
universe@80 496 return ResponseType.NONE;
universe@80 497 }
universe@80 498
universe@97 499 final var projectDao = dao.getProjectDao();
universe@97 500 final var issueDao = dao.getIssueDao();
universe@97 501
universe@86 502 final var viewModel = new IssuesView();
universe@86 503 viewModel.setProject(selection.project);
universe@86 504 if (selection.version == null) {
universe@97 505 viewModel.setIssues(issueDao.list(selection.project));
universe@86 506 } else {
universe@86 507 viewModel.setVersion(selection.version);
universe@97 508 viewModel.setIssues(issueDao.list(selection.version));
universe@86 509 }
universe@86 510 setViewModel(req, viewModel);
universe@80 511
universe@97 512 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project)));
universe@80 513 setContentPage(req, "issues");
universe@80 514 setStylesheet(req, "projects");
universe@80 515
universe@80 516 return ResponseType.HTML;
universe@71 517 }
universe@71 518
universe@64 519 @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET)
universe@80 520 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException {
universe@86 521 final var selection = new SessionSelection(req, dao);
universe@86 522 if (getParameter(req, Integer.class, "issue").isEmpty()) {
universe@86 523 selection.newIssue();
universe@86 524 } else {
universe@86 525 selection.sync();
universe@86 526 }
universe@64 527
universe@86 528 configureEditIssueForm(req, dao, selection);
universe@64 529
universe@64 530 return ResponseType.HTML;
universe@64 531 }
universe@64 532
universe@64 533 @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST)
universe@80 534 public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException {
universe@64 535
universe@86 536 Issue issue = new Issue(-1);
universe@64 537 try {
universe@86 538 issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
universe@86 539 issue.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow()));
universe@75 540 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory);
universe@75 541 getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus);
universe@75 542 issue.setSubject(getParameter(req, String.class, "subject").orElseThrow());
universe@75 543 getParameter(req, Integer.class, "assignee").map(
universe@75 544 userid -> userid >= 0 ? new User(userid) : null
universe@75 545 ).ifPresent(issue::setAssignee);
universe@75 546 getParameter(req, String.class, "description").ifPresent(issue::setDescription);
universe@75 547 getParameter(req, Date.class, "eta").ifPresent(issue::setEta);
universe@83 548
universe@83 549 getParameter(req, Integer[].class, "affected")
universe@83 550 .map(Stream::of)
universe@83 551 .map(stream ->
universe@96 552 stream.map(Version::new).collect(Collectors.toList())
universe@83 553 ).ifPresent(issue::setAffectedVersions);
universe@83 554 getParameter(req, Integer[].class, "resolved")
universe@83 555 .map(Stream::of)
universe@83 556 .map(stream ->
universe@86 557 stream.map(Version::new).collect(Collectors.toList())
universe@83 558 ).ifPresent(issue::setResolvedVersions);
universe@83 559
universe@64 560 dao.getIssueDao().saveOrUpdate(issue);
universe@64 561
universe@96 562 // specifying the issue parameter keeps the edited issue as menu item
universe@96 563 setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId());
universe@74 564 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
universe@75 565 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
universe@64 566 // TODO: set request attribute with error text
universe@64 567 LOG.warn("Form validation failure: {}", ex.getMessage());
universe@64 568 LOG.debug("Details:", ex);
universe@86 569 final var selection = new SessionSelection(req, dao);
universe@86 570 selection.selectIssue(issue);
universe@86 571 final var viewModel = configureEditIssueForm(req, dao, selection);
universe@86 572 // TODO: set Error Text
universe@64 573 }
universe@64 574
universe@64 575 return ResponseType.HTML;
universe@64 576 }
universe@41 577 }

mercurial