1.1 --- a/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sat Aug 22 18:34:36 2020 +0200 1.2 +++ b/src/main/java/de/uapcore/lightpit/modules/ProjectsModule.java Sun Aug 23 15:10:49 2020 +0200 1.3 @@ -39,14 +39,13 @@ 1.4 import javax.servlet.annotation.WebServlet; 1.5 import javax.servlet.http.HttpServletRequest; 1.6 import javax.servlet.http.HttpServletResponse; 1.7 -import javax.servlet.http.HttpSession; 1.8 import java.io.IOException; 1.9 import java.sql.Date; 1.10 import java.sql.SQLException; 1.11 import java.util.ArrayList; 1.12 import java.util.List; 1.13 import java.util.NoSuchElementException; 1.14 -import java.util.Objects; 1.15 +import java.util.Optional; 1.16 import java.util.stream.Collectors; 1.17 import java.util.stream.Stream; 1.18 1.19 @@ -60,178 +59,43 @@ 1.20 1.21 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class); 1.22 1.23 - public static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project"); 1.24 - public static final String SESSION_ATTR_SELECTED_ISSUE = fqn(ProjectsModule.class, "selected_issue"); 1.25 - public static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version"); 1.26 - 1.27 - // TODO: try to get rid of this shit 1.28 - private class SessionSelection { 1.29 - final HttpSession session; 1.30 - final HttpServletRequest req; 1.31 - final DataAccessObjects dao; 1.32 - Project project; 1.33 - Version version; 1.34 - Issue issue; 1.35 - 1.36 - SessionSelection(HttpServletRequest req, DataAccessObjects dao) { 1.37 - this.req = req; 1.38 - this.dao = dao; 1.39 - session = req.getSession(); 1.40 - } 1.41 - 1.42 - void newProject() { 1.43 - project = null; 1.44 - version = null; 1.45 - issue = null; 1.46 - updateAttributes(); 1.47 - project = new Project(-1); 1.48 - updateAttributes(); 1.49 - } 1.50 - 1.51 - void newVersion() throws SQLException { 1.52 - project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); 1.53 - syncProject(); 1.54 - version = null; 1.55 - issue = null; 1.56 - updateAttributes(); 1.57 - version = new Version(-1); 1.58 - version.setProject(project); 1.59 - updateAttributes(); 1.60 - } 1.61 - 1.62 - void newIssue() throws SQLException { 1.63 - project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); 1.64 - syncProject(); 1.65 - version = null; 1.66 - issue = null; 1.67 - updateAttributes(); 1.68 - issue = new Issue(-1); 1.69 - issue.setProject(project); 1.70 - updateAttributes(); 1.71 - } 1.72 - 1.73 - void selectVersion(Version selectedVersion) throws SQLException { 1.74 - issue = null; 1.75 - version = selectedVersion; 1.76 - if (!version.getProject().equals(project)) { 1.77 - project = dao.getProjectDao().find(version.getProject().getId()); 1.78 - } 1.79 - // our object contains more details 1.80 - version.setProject(project); 1.81 - updateAttributes(); 1.82 - } 1.83 - 1.84 - void selectIssue(Issue selectedIssue) throws SQLException { 1.85 - issue = selectedIssue; 1.86 - if (!issue.getProject().equals(project)) { 1.87 - project = dao.getProjectDao().find(issue.getProject().getId()); 1.88 - } 1.89 - // our object contains more details 1.90 - issue.setProject(project); 1.91 - if (!issue.getResolvedVersions().contains(version) 1.92 - && !issue.getAffectedVersions().contains(version)) { 1.93 - version = null; 1.94 - } 1.95 - updateAttributes(); 1.96 - } 1.97 - 1.98 - void syncProject() throws SQLException { 1.99 - final var projectSelection = getParameter(req, Integer.class, "pid"); 1.100 - if (projectSelection.isPresent()) { 1.101 - final var selectedProject = dao.getProjectDao().find(projectSelection.get()); 1.102 - if (!Objects.equals(selectedProject, project)) { 1.103 - // reset version and issue if project changed 1.104 - version = null; 1.105 - issue = null; 1.106 - } 1.107 - project = selectedProject; 1.108 - } else { 1.109 - project = project == null ? null : dao.getProjectDao().find(project.getId()); 1.110 - } 1.111 - } 1.112 - 1.113 - void syncVersion() throws SQLException { 1.114 - final var versionSelection = getParameter(req, Integer.class, "vid"); 1.115 - if (versionSelection.isPresent()) { 1.116 - if (versionSelection.get() < 0) { 1.117 - version = null; 1.118 - } else { 1.119 - final var selectedVersion = dao.getVersionDao().find(versionSelection.get()); 1.120 - if (!Objects.equals(selectedVersion, version)) { 1.121 - issue = null; 1.122 - } 1.123 - selectVersion(selectedVersion); 1.124 - } 1.125 - } else { 1.126 - version = version == null ? null : dao.getVersionDao().find(version.getId()); 1.127 - } 1.128 - } 1.129 - 1.130 - void syncIssue() throws SQLException { 1.131 - final var issueSelection = getParameter(req, Integer.class, "issue"); 1.132 - if (issueSelection.isPresent()) { 1.133 - if (issueSelection.get() < 0) { 1.134 - issue = null; 1.135 - } else { 1.136 - final var selectedIssue = dao.getIssueDao().find(issueSelection.get()); 1.137 - dao.getIssueDao().joinVersionInformation(selectedIssue); 1.138 - selectIssue(selectedIssue); 1.139 - } 1.140 - } else { 1.141 - issue = issue == null ? null : dao.getIssueDao().find(issue.getId()); 1.142 - } 1.143 - } 1.144 - 1.145 - void sync() throws SQLException { 1.146 - project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); 1.147 - version = (Version) session.getAttribute(SESSION_ATTR_SELECTED_VERSION); 1.148 - issue = (Issue) session.getAttribute(SESSION_ATTR_SELECTED_ISSUE); 1.149 - 1.150 - syncProject(); 1.151 - syncVersion(); 1.152 - syncIssue(); 1.153 - 1.154 - updateAttributes(); 1.155 - } 1.156 - 1.157 - private void updateAttributes() { 1.158 - session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, project); 1.159 - session.setAttribute(SESSION_ATTR_SELECTED_VERSION, version); 1.160 - session.setAttribute(SESSION_ATTR_SELECTED_ISSUE, issue); 1.161 - } 1.162 - } 1.163 + private static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project"); 1.164 + private static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version"); 1.165 + private static final String PARAMETER_SELECTED_PROJECT = "pid"; 1.166 + private static final String PARAMETER_SELECTED_VERSION = "vid"; 1.167 1.168 @Override 1.169 protected String getResourceBundleName() { 1.170 return "localization.projects"; 1.171 } 1.172 1.173 - private String queryParams(Project p, Version v, Issue i) { 1.174 - return String.format("pid=%d&vid=%d&issue=%d", 1.175 + private String queryParams(Project p, Version v) { 1.176 + return String.format("pid=%d&vid=%d", 1.177 p == null ? -1 : p.getId(), 1.178 - v == null ? -1 : v.getId(), 1.179 - i == null ? -1 : i.getId() 1.180 + v == null ? -1 : v.getId() 1.181 ); 1.182 } 1.183 1.184 /** 1.185 * Creates the navigation menu. 1.186 * 1.187 - * @param projects the list of projects 1.188 - * @param selection the currently selected objects 1.189 - * @param projInfo info about the currently selected project or null 1.190 - * @return a dynamic navigation menu trying to display as many levels as possible 1.191 + * @param req the servlet request 1.192 + * @param viewModel the current view model 1.193 */ 1.194 - private List<MenuEntry> getNavMenu(List<Project> projects, SessionSelection selection, ProjectInfo projInfo) { 1.195 + private void setNavigationMenu(HttpServletRequest req, ProjectView viewModel) { 1.196 + final Project selectedProject = Optional.ofNullable(viewModel.getProjectInfo()).map(ProjectInfo::getProject).orElse(null); 1.197 + 1.198 final var navigation = new ArrayList<MenuEntry>(); 1.199 1.200 - for (Project proj : projects) { 1.201 + for (ProjectInfo plistInfo : viewModel.getProjectList()) { 1.202 + final var proj = plistInfo.getProject(); 1.203 final var projEntry = new MenuEntry( 1.204 proj.getName(), 1.205 - "projects/view?pid=" + proj.getId() 1.206 + "projects/view?" + queryParams(proj, null) 1.207 ); 1.208 navigation.add(projEntry); 1.209 - if (proj.equals(selection.project)) { 1.210 + if (proj.equals(selectedProject)) { 1.211 + final var projInfo = viewModel.getProjectInfo(); 1.212 projEntry.setActive(true); 1.213 1.214 // **************** 1.215 @@ -239,8 +103,8 @@ 1.216 // **************** 1.217 { 1.218 final var entry = new MenuEntry(1, 1.219 - new ResourceKey("localization.projects", "menu.versions"), 1.220 - "projects/view?" + queryParams(proj, null, null) 1.221 + new ResourceKey(getResourceBundleName(), "menu.versions"), 1.222 + "projects/view?" + queryParams(proj, null) 1.223 ); 1.224 navigation.add(entry); 1.225 } 1.226 @@ -248,19 +112,19 @@ 1.227 final var level2 = new ArrayList<MenuEntry>(); 1.228 { 1.229 final var entry = new MenuEntry( 1.230 - new ResourceKey("localization.projects", "filter.all"), 1.231 - "projects/view?" + queryParams(proj, null, null) 1.232 + new ResourceKey(getResourceBundleName(), "filter.all"), 1.233 + "projects/view?" + queryParams(proj, null) 1.234 ); 1.235 - if (selection.version == null) entry.setActive(true); 1.236 + if (viewModel.getVersionFilter() == null) entry.setActive(true); 1.237 level2.add(entry); 1.238 } 1.239 1.240 for (Version version : projInfo.getVersions()) { 1.241 final var entry = new MenuEntry( 1.242 version.getName(), 1.243 - "projects/versions/view?" + queryParams(proj, version, null) 1.244 + "projects/view?" + queryParams(proj, version) 1.245 ); 1.246 - if (version.equals(selection.version)) entry.setActive(true); 1.247 + if (version.equals(viewModel.getVersionFilter())) entry.setActive(true); 1.248 level2.add(entry); 1.249 } 1.250 1.251 @@ -269,69 +133,85 @@ 1.252 } 1.253 } 1.254 1.255 - return navigation; 1.256 + setNavigationMenu(req, navigation); 1.257 + } 1.258 + 1.259 + private int syncParamWithSession(HttpServletRequest req, String param, String attr) { 1.260 + final var session = req.getSession(); 1.261 + final var idParam = getParameter(req, Integer.class, param); 1.262 + final int id; 1.263 + if (idParam.isPresent()) { 1.264 + id = idParam.get(); 1.265 + session.setAttribute(attr, id); 1.266 + } else { 1.267 + id = Optional.ofNullable(session.getAttribute(attr)).map(x->(Integer)x).orElse(-1); 1.268 + } 1.269 + return id; 1.270 + } 1.271 + 1.272 + private void populate(ProjectView viewModel, HttpServletRequest req, DataAccessObjects dao) throws SQLException { 1.273 + final var projectDao = dao.getProjectDao(); 1.274 + final var versionDao = dao.getVersionDao(); 1.275 + 1.276 + projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); 1.277 + 1.278 + // Select Project 1.279 + final int pid = syncParamWithSession(req, PARAMETER_SELECTED_PROJECT, SESSION_ATTR_SELECTED_PROJECT); 1.280 + if (pid >= 0) { 1.281 + final var project = projectDao.find(pid); 1.282 + final var info = new ProjectInfo(project); 1.283 + info.setVersions(versionDao.list(project)); 1.284 + info.setIssueSummary(projectDao.getIssueSummary(project)); 1.285 + viewModel.setProjectInfo(info); 1.286 + } 1.287 + 1.288 + // Select Version 1.289 + final int vid = syncParamWithSession(req, PARAMETER_SELECTED_VERSION, SESSION_ATTR_SELECTED_VERSION); 1.290 + if (vid >= 0) { 1.291 + viewModel.setVersionFilter(versionDao.find(vid)); 1.292 + } 1.293 + } 1.294 + 1.295 + private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) { 1.296 + setViewModel(req, viewModel); 1.297 + setContentPage(req, name); 1.298 + setStylesheet(req, "projects"); 1.299 + setNavigationMenu(req, viewModel); 1.300 + return ResponseType.HTML; 1.301 } 1.302 1.303 @RequestMapping(method = HttpMethod.GET) 1.304 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 1.305 - final var sessionSelection = new SessionSelection(req, dao); 1.306 - sessionSelection.sync(); 1.307 + final var viewModel = new ProjectView(); 1.308 + populate(viewModel, req, dao); 1.309 1.310 final var projectDao = dao.getProjectDao(); 1.311 final var versionDao = dao.getVersionDao(); 1.312 1.313 - final var projectList = projectDao.list(); 1.314 - 1.315 - final var viewModel = new ProjectIndexView(); 1.316 - for (var project : projectList) { 1.317 - final var info = new ProjectInfo(project); 1.318 - info.setVersions(versionDao.list(project)); 1.319 - info.setIssueSummary(projectDao.getIssueSummary(project)); 1.320 - viewModel.getProjects().add(info); 1.321 + for (var info : viewModel.getProjectList()) { 1.322 + info.setVersions(versionDao.list(info.getProject())); 1.323 + info.setIssueSummary(projectDao.getIssueSummary(info.getProject())); 1.324 } 1.325 1.326 - setViewModel(req, viewModel); 1.327 - setContentPage(req, "projects"); 1.328 - setStylesheet(req, "projects"); 1.329 - 1.330 - setNavigationMenu(req, getNavMenu(projectList, sessionSelection, currentProjectInfo(dao, sessionSelection.project))); 1.331 - 1.332 - return ResponseType.HTML; 1.333 + return forwardView(req, viewModel, "projects"); 1.334 } 1.335 1.336 - private ProjectInfo currentProjectInfo(DataAccessObjects dao, Project project) throws SQLException { 1.337 - if (project == null) return null; 1.338 - final var projectDao = dao.getProjectDao(); 1.339 - final var versionDao = dao.getVersionDao(); 1.340 - 1.341 - final var info = new ProjectInfo(project); 1.342 - info.setVersions(versionDao.list(project)); 1.343 - info.setIssueSummary(projectDao.getIssueSummary(project)); 1.344 - return info; 1.345 - } 1.346 - 1.347 - private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { 1.348 - final var viewModel = new ProjectEditView(); 1.349 - viewModel.setProject(selection.project); 1.350 + private void configure(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException { 1.351 + viewModel.setProject(project); 1.352 viewModel.setUsers(dao.getUserDao().list()); 1.353 - setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); 1.354 - setViewModel(req, viewModel); 1.355 - setContentPage(req, "project-form"); 1.356 - return viewModel; 1.357 } 1.358 1.359 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) 1.360 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 1.361 - final var selection = new SessionSelection(req, dao); 1.362 - if (getParameter(req, Integer.class, "pid").isEmpty()) { 1.363 - selection.newProject(); 1.364 - } else { 1.365 - selection.sync(); 1.366 - } 1.367 + final var viewModel = new ProjectEditView(); 1.368 + populate(viewModel, req, dao); 1.369 1.370 - configureEditForm(req, dao, selection); 1.371 + final var project = Optional.ofNullable(viewModel.getProjectInfo()) 1.372 + .map(ProjectInfo::getProject) 1.373 + .orElse(new Project(-1)); 1.374 + configure(viewModel, project, dao); 1.375 1.376 - return ResponseType.HTML; 1.377 + return forwardView(req, viewModel, "project-form"); 1.378 } 1.379 1.380 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) 1.381 @@ -339,7 +219,7 @@ 1.382 1.383 Project project = new Project(-1); 1.384 try { 1.385 - project = new Project(getParameter(req, Integer.class, "id").orElseThrow()); 1.386 + project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); 1.387 project.setName(getParameter(req, String.class, "name").orElseThrow()); 1.388 getParameter(req, String.class, "description").ifPresent(project::setDescription); 1.389 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl); 1.390 @@ -349,99 +229,61 @@ 1.391 1.392 dao.getProjectDao().saveOrUpdate(project); 1.393 1.394 - setRedirectLocation(req, "./projects/"); 1.395 + setRedirectLocation(req, "./projects/view?pid="+project.getId()); 1.396 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 1.397 LOG.debug("Successfully updated project {}", project.getName()); 1.398 + 1.399 + return ResponseType.HTML; 1.400 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 1.401 LOG.warn("Form validation failure: {}", ex.getMessage()); 1.402 LOG.debug("Details:", ex); 1.403 - final var selection = new SessionSelection(req, dao); 1.404 - selection.project = project; 1.405 - final var vm = configureEditForm(req, dao, selection); 1.406 - vm.setErrorText(ex.getMessage()); // TODO: error text 1.407 + final var viewModel = new ProjectEditView(); 1.408 + populate(viewModel, req, dao); 1.409 + configure(viewModel, project, dao); 1.410 + // TODO: error text 1.411 + return forwardView(req, viewModel, "project-form"); 1.412 } 1.413 - 1.414 - return ResponseType.HTML; 1.415 } 1.416 1.417 @RequestMapping(requestPath = "view", method = HttpMethod.GET) 1.418 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { 1.419 - final var selection = new SessionSelection(req, dao); 1.420 - selection.sync(); 1.421 + final var viewModel = new ProjectDetailsView(); 1.422 + populate(viewModel, req, dao); 1.423 1.424 - if (selection.project == null) { 1.425 + if (viewModel.getProjectInfo() == null) { 1.426 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); 1.427 return ResponseType.NONE; 1.428 } 1.429 1.430 - final var projectDao = dao.getProjectDao(); 1.431 - final var versionDao = dao.getVersionDao(); 1.432 final var issueDao = dao.getIssueDao(); 1.433 1.434 - final var viewModel = new ProjectView(selection.project); 1.435 - final var issues = issueDao.list(selection.project); 1.436 + final var project = viewModel.getProjectInfo().getProject(); 1.437 + 1.438 + final var detailView = viewModel.getProjectDetails(); 1.439 + if (viewModel.getVersionFilter() != null) { 1.440 + detailView.updateVersionInfo(List.of(viewModel.getVersionFilter())); 1.441 + } else { 1.442 + detailView.updateVersionInfo(viewModel.getProjectInfo().getVersions()); 1.443 + } 1.444 + final var issues = issueDao.list(project); 1.445 for (var issue : issues) issueDao.joinVersionInformation(issue); 1.446 - viewModel.setIssues(issues); 1.447 - // TODO: fix duplicated selection of versions (projectInfo also contains these infos) 1.448 - viewModel.setVersions(versionDao.list(selection.project)); 1.449 - viewModel.updateVersionInfo(); 1.450 - setViewModel(req, viewModel); 1.451 + detailView.setIssues(issues); 1.452 1.453 - setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); 1.454 - setContentPage(req, "project-details"); 1.455 - setStylesheet(req, "projects"); 1.456 - 1.457 - return ResponseType.HTML; 1.458 - } 1.459 - 1.460 - @RequestMapping(requestPath = "versions/view", method = HttpMethod.GET) 1.461 - public ResponseType viewVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { 1.462 - final var selection = new SessionSelection(req, dao); 1.463 - selection.sync(); 1.464 - if (selection.version == null) { 1.465 - resp.sendError(HttpServletResponse.SC_NOT_FOUND); 1.466 - return ResponseType.NONE; 1.467 - } 1.468 - 1.469 - final var projectDao = dao.getProjectDao(); 1.470 - final var issueDao = dao.getIssueDao(); 1.471 - 1.472 - final var viewModel = new VersionView(selection.version); 1.473 - final var issues = issueDao.list(selection.version); 1.474 - for (var issue : issues) issueDao.joinVersionInformation(issue); 1.475 - viewModel.setIssues(issues); 1.476 - setViewModel(req, viewModel); 1.477 - 1.478 - setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); 1.479 - setContentPage(req, "version"); 1.480 - setStylesheet(req, "projects"); 1.481 - 1.482 - return ResponseType.HTML; 1.483 - } 1.484 - 1.485 - private VersionEditView configureEditVersionForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { 1.486 - final var viewModel = new VersionEditView(selection.version); 1.487 - if (selection.version.getProject() == null) { 1.488 - viewModel.setProjects(dao.getProjectDao().list()); 1.489 - } 1.490 - setViewModel(req, viewModel); 1.491 - setContentPage(req, "version-form"); 1.492 - setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); 1.493 - return viewModel; 1.494 + return forwardView(req, viewModel, "project-details"); 1.495 } 1.496 1.497 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) 1.498 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 1.499 - final var selection = new SessionSelection(req, dao); 1.500 - if (getParameter(req, Integer.class, "vid").isEmpty()) { 1.501 - selection.newVersion(); 1.502 + final var viewModel = new VersionEditView(); 1.503 + populate(viewModel, req, dao); 1.504 + 1.505 + if (viewModel.getVersionFilter() == null) { 1.506 + viewModel.setVersion(new Version(-1)); 1.507 } else { 1.508 - selection.sync(); 1.509 + viewModel.setVersion(viewModel.getVersionFilter()); 1.510 } 1.511 1.512 - configureEditVersionForm(req, dao, selection); 1.513 - 1.514 - return ResponseType.HTML; 1.515 + return forwardView(req, viewModel, "version-form"); 1.516 } 1.517 1.518 @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST) 1.519 @@ -462,77 +304,43 @@ 1.520 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 1.521 LOG.warn("Form validation failure: {}", ex.getMessage()); 1.522 LOG.debug("Details:", ex); 1.523 - final var selection = new SessionSelection(req, dao); 1.524 - selection.selectVersion(version); 1.525 - final var viewModel = configureEditVersionForm(req, dao, selection); 1.526 + final var viewModel = new VersionEditView(); 1.527 + populate(viewModel, req, dao); 1.528 + viewModel.setVersion(version); 1.529 // TODO: set Error Text 1.530 + return forwardView(req, viewModel, "version-form"); 1.531 } 1.532 1.533 return ResponseType.HTML; 1.534 } 1.535 1.536 - private IssueEditView configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { 1.537 - final var viewModel = new IssueEditView(selection.issue); 1.538 - 1.539 - if (selection.issue.getProject() == null) { 1.540 - viewModel.setProjects(dao.getProjectDao().list()); 1.541 - } else { 1.542 - viewModel.setVersions(dao.getVersionDao().list(selection.issue.getProject())); 1.543 - } 1.544 + private void configure(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException { 1.545 + issue.setProject(viewModel.getProjectInfo().getProject()); 1.546 + viewModel.setIssue(issue); 1.547 + viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); 1.548 viewModel.setUsers(dao.getUserDao().list()); 1.549 - setViewModel(req, viewModel); 1.550 - 1.551 - setContentPage(req, "issue-form"); 1.552 - setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); 1.553 - return viewModel; 1.554 - } 1.555 - 1.556 - @RequestMapping(requestPath = "issues/", method = HttpMethod.GET) 1.557 - public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { 1.558 - final var selection = new SessionSelection(req, dao); 1.559 - selection.sync(); 1.560 - if (selection.project == null) { 1.561 - resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); 1.562 - return ResponseType.NONE; 1.563 - } 1.564 - 1.565 - final var projectDao = dao.getProjectDao(); 1.566 - final var issueDao = dao.getIssueDao(); 1.567 - 1.568 - final var viewModel = new IssuesView(); 1.569 - viewModel.setProject(selection.project); 1.570 - if (selection.version == null) { 1.571 - viewModel.setIssues(issueDao.list(selection.project)); 1.572 - } else { 1.573 - viewModel.setVersion(selection.version); 1.574 - viewModel.setIssues(issueDao.list(selection.version)); 1.575 - } 1.576 - setViewModel(req, viewModel); 1.577 - 1.578 - setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); 1.579 - setContentPage(req, "issues"); 1.580 - setStylesheet(req, "projects"); 1.581 - 1.582 - return ResponseType.HTML; 1.583 } 1.584 1.585 @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET) 1.586 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { 1.587 - final var selection = new SessionSelection(req, dao); 1.588 - if (getParameter(req, Integer.class, "issue").isEmpty()) { 1.589 - selection.newIssue(); 1.590 + final var viewModel = new IssueEditView(); 1.591 + 1.592 + final var issueParam = getParameter(req, Integer.class, "issue"); 1.593 + if (issueParam.isPresent()) { 1.594 + final var issue = dao.getIssueDao().find(issueParam.get()); 1.595 + req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, issue.getProject().getId()); 1.596 + populate(viewModel, req, dao); 1.597 + configure(viewModel, issue, dao); 1.598 } else { 1.599 - selection.sync(); 1.600 + populate(viewModel, req, dao); 1.601 + configure(viewModel, new Issue(-1), dao); 1.602 } 1.603 1.604 - configureEditIssueForm(req, dao, selection); 1.605 - 1.606 - return ResponseType.HTML; 1.607 + return forwardView(req, viewModel, "issue-form"); 1.608 } 1.609 1.610 @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST) 1.611 public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { 1.612 - 1.613 Issue issue = new Issue(-1); 1.614 try { 1.615 issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); 1.616 @@ -560,16 +368,16 @@ 1.617 dao.getIssueDao().saveOrUpdate(issue); 1.618 1.619 // specifying the issue parameter keeps the edited issue as menu item 1.620 - setRedirectLocation(req, "./projects/issues/?issue=" + issue.getId()); 1.621 + setRedirectLocation(req, "./projects/view/?pid=" + issue.getProject().getId()); 1.622 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 1.623 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 1.624 // TODO: set request attribute with error text 1.625 LOG.warn("Form validation failure: {}", ex.getMessage()); 1.626 LOG.debug("Details:", ex); 1.627 - final var selection = new SessionSelection(req, dao); 1.628 - selection.selectIssue(issue); 1.629 - final var viewModel = configureEditIssueForm(req, dao, selection); 1.630 + final var viewModel = new IssueEditView(); 1.631 + configure(viewModel, issue, dao); 1.632 // TODO: set Error Text 1.633 + return forwardView(req, viewModel, "issue-form"); 1.634 } 1.635 1.636 return ResponseType.HTML;