58 ) |
57 ) |
59 public final class ProjectsModule extends AbstractLightPITServlet { |
58 public final class ProjectsModule extends AbstractLightPITServlet { |
60 |
59 |
61 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class); |
60 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class); |
62 |
61 |
63 public static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project"); |
62 private static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project"); |
64 public static final String SESSION_ATTR_SELECTED_ISSUE = fqn(ProjectsModule.class, "selected_issue"); |
63 private static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version"); |
65 public static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version"); |
64 private static final String PARAMETER_SELECTED_PROJECT = "pid"; |
66 |
65 private static final String PARAMETER_SELECTED_VERSION = "vid"; |
67 // TODO: try to get rid of this shit |
|
68 private class SessionSelection { |
|
69 final HttpSession session; |
|
70 final HttpServletRequest req; |
|
71 final DataAccessObjects dao; |
|
72 Project project; |
|
73 Version version; |
|
74 Issue issue; |
|
75 |
|
76 SessionSelection(HttpServletRequest req, DataAccessObjects dao) { |
|
77 this.req = req; |
|
78 this.dao = dao; |
|
79 session = req.getSession(); |
|
80 } |
|
81 |
|
82 void newProject() { |
|
83 project = null; |
|
84 version = null; |
|
85 issue = null; |
|
86 updateAttributes(); |
|
87 project = new Project(-1); |
|
88 updateAttributes(); |
|
89 } |
|
90 |
|
91 void newVersion() throws SQLException { |
|
92 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); |
|
93 syncProject(); |
|
94 version = null; |
|
95 issue = null; |
|
96 updateAttributes(); |
|
97 version = new Version(-1); |
|
98 version.setProject(project); |
|
99 updateAttributes(); |
|
100 } |
|
101 |
|
102 void newIssue() throws SQLException { |
|
103 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); |
|
104 syncProject(); |
|
105 version = null; |
|
106 issue = null; |
|
107 updateAttributes(); |
|
108 issue = new Issue(-1); |
|
109 issue.setProject(project); |
|
110 updateAttributes(); |
|
111 } |
|
112 |
|
113 void selectVersion(Version selectedVersion) throws SQLException { |
|
114 issue = null; |
|
115 version = selectedVersion; |
|
116 if (!version.getProject().equals(project)) { |
|
117 project = dao.getProjectDao().find(version.getProject().getId()); |
|
118 } |
|
119 // our object contains more details |
|
120 version.setProject(project); |
|
121 updateAttributes(); |
|
122 } |
|
123 |
|
124 void selectIssue(Issue selectedIssue) throws SQLException { |
|
125 issue = selectedIssue; |
|
126 if (!issue.getProject().equals(project)) { |
|
127 project = dao.getProjectDao().find(issue.getProject().getId()); |
|
128 } |
|
129 // our object contains more details |
|
130 issue.setProject(project); |
|
131 if (!issue.getResolvedVersions().contains(version) |
|
132 && !issue.getAffectedVersions().contains(version)) { |
|
133 version = null; |
|
134 } |
|
135 updateAttributes(); |
|
136 } |
|
137 |
|
138 void syncProject() throws SQLException { |
|
139 final var projectSelection = getParameter(req, Integer.class, "pid"); |
|
140 if (projectSelection.isPresent()) { |
|
141 final var selectedProject = dao.getProjectDao().find(projectSelection.get()); |
|
142 if (!Objects.equals(selectedProject, project)) { |
|
143 // reset version and issue if project changed |
|
144 version = null; |
|
145 issue = null; |
|
146 } |
|
147 project = selectedProject; |
|
148 } else { |
|
149 project = project == null ? null : dao.getProjectDao().find(project.getId()); |
|
150 } |
|
151 } |
|
152 |
|
153 void syncVersion() throws SQLException { |
|
154 final var versionSelection = getParameter(req, Integer.class, "vid"); |
|
155 if (versionSelection.isPresent()) { |
|
156 if (versionSelection.get() < 0) { |
|
157 version = null; |
|
158 } else { |
|
159 final var selectedVersion = dao.getVersionDao().find(versionSelection.get()); |
|
160 if (!Objects.equals(selectedVersion, version)) { |
|
161 issue = null; |
|
162 } |
|
163 selectVersion(selectedVersion); |
|
164 } |
|
165 } else { |
|
166 version = version == null ? null : dao.getVersionDao().find(version.getId()); |
|
167 } |
|
168 } |
|
169 |
|
170 void syncIssue() throws SQLException { |
|
171 final var issueSelection = getParameter(req, Integer.class, "issue"); |
|
172 if (issueSelection.isPresent()) { |
|
173 if (issueSelection.get() < 0) { |
|
174 issue = null; |
|
175 } else { |
|
176 final var selectedIssue = dao.getIssueDao().find(issueSelection.get()); |
|
177 dao.getIssueDao().joinVersionInformation(selectedIssue); |
|
178 selectIssue(selectedIssue); |
|
179 } |
|
180 } else { |
|
181 issue = issue == null ? null : dao.getIssueDao().find(issue.getId()); |
|
182 } |
|
183 } |
|
184 |
|
185 void sync() throws SQLException { |
|
186 project = (Project) session.getAttribute(SESSION_ATTR_SELECTED_PROJECT); |
|
187 version = (Version) session.getAttribute(SESSION_ATTR_SELECTED_VERSION); |
|
188 issue = (Issue) session.getAttribute(SESSION_ATTR_SELECTED_ISSUE); |
|
189 |
|
190 syncProject(); |
|
191 syncVersion(); |
|
192 syncIssue(); |
|
193 |
|
194 updateAttributes(); |
|
195 } |
|
196 |
|
197 private void updateAttributes() { |
|
198 session.setAttribute(SESSION_ATTR_SELECTED_PROJECT, project); |
|
199 session.setAttribute(SESSION_ATTR_SELECTED_VERSION, version); |
|
200 session.setAttribute(SESSION_ATTR_SELECTED_ISSUE, issue); |
|
201 } |
|
202 } |
|
203 |
66 |
204 @Override |
67 @Override |
205 protected String getResourceBundleName() { |
68 protected String getResourceBundleName() { |
206 return "localization.projects"; |
69 return "localization.projects"; |
207 } |
70 } |
208 |
71 |
209 private String queryParams(Project p, Version v, Issue i) { |
72 private String queryParams(Project p, Version v) { |
210 return String.format("pid=%d&vid=%d&issue=%d", |
73 return String.format("pid=%d&vid=%d", |
211 p == null ? -1 : p.getId(), |
74 p == null ? -1 : p.getId(), |
212 v == null ? -1 : v.getId(), |
75 v == null ? -1 : v.getId() |
213 i == null ? -1 : i.getId() |
|
214 ); |
76 ); |
215 } |
77 } |
216 |
78 |
217 /** |
79 /** |
218 * Creates the navigation menu. |
80 * Creates the navigation menu. |
219 * |
81 * |
220 * @param projects the list of projects |
82 * @param req the servlet request |
221 * @param selection the currently selected objects |
83 * @param viewModel the current view model |
222 * @param projInfo info about the currently selected project or null |
|
223 * @return a dynamic navigation menu trying to display as many levels as possible |
|
224 */ |
84 */ |
225 private List<MenuEntry> getNavMenu(List<Project> projects, SessionSelection selection, ProjectInfo projInfo) { |
85 private void setNavigationMenu(HttpServletRequest req, ProjectView viewModel) { |
|
86 final Project selectedProject = Optional.ofNullable(viewModel.getProjectInfo()).map(ProjectInfo::getProject).orElse(null); |
|
87 |
226 final var navigation = new ArrayList<MenuEntry>(); |
88 final var navigation = new ArrayList<MenuEntry>(); |
227 |
89 |
228 for (Project proj : projects) { |
90 for (ProjectInfo plistInfo : viewModel.getProjectList()) { |
|
91 final var proj = plistInfo.getProject(); |
229 final var projEntry = new MenuEntry( |
92 final var projEntry = new MenuEntry( |
230 proj.getName(), |
93 proj.getName(), |
231 "projects/view?pid=" + proj.getId() |
94 "projects/view?" + queryParams(proj, null) |
232 ); |
95 ); |
233 navigation.add(projEntry); |
96 navigation.add(projEntry); |
234 if (proj.equals(selection.project)) { |
97 if (proj.equals(selectedProject)) { |
|
98 final var projInfo = viewModel.getProjectInfo(); |
235 projEntry.setActive(true); |
99 projEntry.setActive(true); |
236 |
100 |
237 // **************** |
101 // **************** |
238 // Versions Section |
102 // Versions Section |
239 // **************** |
103 // **************** |
240 { |
104 { |
241 final var entry = new MenuEntry(1, |
105 final var entry = new MenuEntry(1, |
242 new ResourceKey("localization.projects", "menu.versions"), |
106 new ResourceKey(getResourceBundleName(), "menu.versions"), |
243 "projects/view?" + queryParams(proj, null, null) |
107 "projects/view?" + queryParams(proj, null) |
244 ); |
108 ); |
245 navigation.add(entry); |
109 navigation.add(entry); |
246 } |
110 } |
247 |
111 |
248 final var level2 = new ArrayList<MenuEntry>(); |
112 final var level2 = new ArrayList<MenuEntry>(); |
249 { |
113 { |
250 final var entry = new MenuEntry( |
114 final var entry = new MenuEntry( |
251 new ResourceKey("localization.projects", "filter.all"), |
115 new ResourceKey(getResourceBundleName(), "filter.all"), |
252 "projects/view?" + queryParams(proj, null, null) |
116 "projects/view?" + queryParams(proj, null) |
253 ); |
117 ); |
254 if (selection.version == null) entry.setActive(true); |
118 if (viewModel.getVersionFilter() == null) entry.setActive(true); |
255 level2.add(entry); |
119 level2.add(entry); |
256 } |
120 } |
257 |
121 |
258 for (Version version : projInfo.getVersions()) { |
122 for (Version version : projInfo.getVersions()) { |
259 final var entry = new MenuEntry( |
123 final var entry = new MenuEntry( |
260 version.getName(), |
124 version.getName(), |
261 "projects/versions/view?" + queryParams(proj, version, null) |
125 "projects/view?" + queryParams(proj, version) |
262 ); |
126 ); |
263 if (version.equals(selection.version)) entry.setActive(true); |
127 if (version.equals(viewModel.getVersionFilter())) entry.setActive(true); |
264 level2.add(entry); |
128 level2.add(entry); |
265 } |
129 } |
266 |
130 |
267 level2.forEach(e -> e.setLevel(2)); |
131 level2.forEach(e -> e.setLevel(2)); |
268 navigation.addAll(level2); |
132 navigation.addAll(level2); |
269 } |
133 } |
270 } |
134 } |
271 |
135 |
272 return navigation; |
136 setNavigationMenu(req, navigation); |
273 } |
137 } |
274 |
138 |
275 @RequestMapping(method = HttpMethod.GET) |
139 private int syncParamWithSession(HttpServletRequest req, String param, String attr) { |
276 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
140 final var session = req.getSession(); |
277 final var sessionSelection = new SessionSelection(req, dao); |
141 final var idParam = getParameter(req, Integer.class, param); |
278 sessionSelection.sync(); |
142 final int id; |
279 |
143 if (idParam.isPresent()) { |
|
144 id = idParam.get(); |
|
145 session.setAttribute(attr, id); |
|
146 } else { |
|
147 id = Optional.ofNullable(session.getAttribute(attr)).map(x->(Integer)x).orElse(-1); |
|
148 } |
|
149 return id; |
|
150 } |
|
151 |
|
152 private void populate(ProjectView viewModel, HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
280 final var projectDao = dao.getProjectDao(); |
153 final var projectDao = dao.getProjectDao(); |
281 final var versionDao = dao.getVersionDao(); |
154 final var versionDao = dao.getVersionDao(); |
282 |
155 |
283 final var projectList = projectDao.list(); |
156 projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); |
284 |
157 |
285 final var viewModel = new ProjectIndexView(); |
158 // Select Project |
286 for (var project : projectList) { |
159 final int pid = syncParamWithSession(req, PARAMETER_SELECTED_PROJECT, SESSION_ATTR_SELECTED_PROJECT); |
|
160 if (pid >= 0) { |
|
161 final var project = projectDao.find(pid); |
287 final var info = new ProjectInfo(project); |
162 final var info = new ProjectInfo(project); |
288 info.setVersions(versionDao.list(project)); |
163 info.setVersions(versionDao.list(project)); |
289 info.setIssueSummary(projectDao.getIssueSummary(project)); |
164 info.setIssueSummary(projectDao.getIssueSummary(project)); |
290 viewModel.getProjects().add(info); |
165 viewModel.setProjectInfo(info); |
291 } |
166 } |
292 |
167 |
|
168 // Select Version |
|
169 final int vid = syncParamWithSession(req, PARAMETER_SELECTED_VERSION, SESSION_ATTR_SELECTED_VERSION); |
|
170 if (vid >= 0) { |
|
171 viewModel.setVersionFilter(versionDao.find(vid)); |
|
172 } |
|
173 } |
|
174 |
|
175 private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) { |
293 setViewModel(req, viewModel); |
176 setViewModel(req, viewModel); |
294 setContentPage(req, "projects"); |
177 setContentPage(req, name); |
295 setStylesheet(req, "projects"); |
178 setStylesheet(req, "projects"); |
296 |
179 setNavigationMenu(req, viewModel); |
297 setNavigationMenu(req, getNavMenu(projectList, sessionSelection, currentProjectInfo(dao, sessionSelection.project))); |
|
298 |
|
299 return ResponseType.HTML; |
180 return ResponseType.HTML; |
300 } |
181 } |
301 |
182 |
302 private ProjectInfo currentProjectInfo(DataAccessObjects dao, Project project) throws SQLException { |
183 @RequestMapping(method = HttpMethod.GET) |
303 if (project == null) return null; |
184 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
|
185 final var viewModel = new ProjectView(); |
|
186 populate(viewModel, req, dao); |
|
187 |
304 final var projectDao = dao.getProjectDao(); |
188 final var projectDao = dao.getProjectDao(); |
305 final var versionDao = dao.getVersionDao(); |
189 final var versionDao = dao.getVersionDao(); |
306 |
190 |
307 final var info = new ProjectInfo(project); |
191 for (var info : viewModel.getProjectList()) { |
308 info.setVersions(versionDao.list(project)); |
192 info.setVersions(versionDao.list(info.getProject())); |
309 info.setIssueSummary(projectDao.getIssueSummary(project)); |
193 info.setIssueSummary(projectDao.getIssueSummary(info.getProject())); |
310 return info; |
194 } |
311 } |
195 |
312 |
196 return forwardView(req, viewModel, "projects"); |
313 private ProjectEditView configureEditForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
197 } |
314 final var viewModel = new ProjectEditView(); |
198 |
315 viewModel.setProject(selection.project); |
199 private void configure(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException { |
|
200 viewModel.setProject(project); |
316 viewModel.setUsers(dao.getUserDao().list()); |
201 viewModel.setUsers(dao.getUserDao().list()); |
317 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
|
318 setViewModel(req, viewModel); |
|
319 setContentPage(req, "project-form"); |
|
320 return viewModel; |
|
321 } |
202 } |
322 |
203 |
323 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
204 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) |
324 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
205 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
325 final var selection = new SessionSelection(req, dao); |
206 final var viewModel = new ProjectEditView(); |
326 if (getParameter(req, Integer.class, "pid").isEmpty()) { |
207 populate(viewModel, req, dao); |
327 selection.newProject(); |
208 |
328 } else { |
209 final var project = Optional.ofNullable(viewModel.getProjectInfo()) |
329 selection.sync(); |
210 .map(ProjectInfo::getProject) |
330 } |
211 .orElse(new Project(-1)); |
331 |
212 configure(viewModel, project, dao); |
332 configureEditForm(req, dao, selection); |
213 |
333 |
214 return forwardView(req, viewModel, "project-form"); |
334 return ResponseType.HTML; |
|
335 } |
215 } |
336 |
216 |
337 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) |
217 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) |
338 public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
218 public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
339 |
219 |
340 Project project = new Project(-1); |
220 Project project = new Project(-1); |
341 try { |
221 try { |
342 project = new Project(getParameter(req, Integer.class, "id").orElseThrow()); |
222 project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); |
343 project.setName(getParameter(req, String.class, "name").orElseThrow()); |
223 project.setName(getParameter(req, String.class, "name").orElseThrow()); |
344 getParameter(req, String.class, "description").ifPresent(project::setDescription); |
224 getParameter(req, String.class, "description").ifPresent(project::setDescription); |
345 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl); |
225 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl); |
346 getParameter(req, Integer.class, "owner").map( |
226 getParameter(req, Integer.class, "owner").map( |
347 ownerId -> ownerId >= 0 ? new User(ownerId) : null |
227 ownerId -> ownerId >= 0 ? new User(ownerId) : null |
348 ).ifPresent(project::setOwner); |
228 ).ifPresent(project::setOwner); |
349 |
229 |
350 dao.getProjectDao().saveOrUpdate(project); |
230 dao.getProjectDao().saveOrUpdate(project); |
351 |
231 |
352 setRedirectLocation(req, "./projects/"); |
232 setRedirectLocation(req, "./projects/view?pid="+project.getId()); |
353 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
233 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
354 LOG.debug("Successfully updated project {}", project.getName()); |
234 LOG.debug("Successfully updated project {}", project.getName()); |
|
235 |
|
236 return ResponseType.HTML; |
355 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
237 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
356 LOG.warn("Form validation failure: {}", ex.getMessage()); |
238 LOG.warn("Form validation failure: {}", ex.getMessage()); |
357 LOG.debug("Details:", ex); |
239 LOG.debug("Details:", ex); |
358 final var selection = new SessionSelection(req, dao); |
240 final var viewModel = new ProjectEditView(); |
359 selection.project = project; |
241 populate(viewModel, req, dao); |
360 final var vm = configureEditForm(req, dao, selection); |
242 configure(viewModel, project, dao); |
361 vm.setErrorText(ex.getMessage()); // TODO: error text |
243 // TODO: error text |
362 } |
244 return forwardView(req, viewModel, "project-form"); |
363 |
245 } |
364 return ResponseType.HTML; |
|
365 } |
246 } |
366 |
247 |
367 @RequestMapping(requestPath = "view", method = HttpMethod.GET) |
248 @RequestMapping(requestPath = "view", method = HttpMethod.GET) |
368 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
249 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
369 final var selection = new SessionSelection(req, dao); |
250 final var viewModel = new ProjectDetailsView(); |
370 selection.sync(); |
251 populate(viewModel, req, dao); |
371 |
252 |
372 if (selection.project == null) { |
253 if (viewModel.getProjectInfo() == null) { |
373 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
254 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
374 return ResponseType.NONE; |
255 return ResponseType.NONE; |
375 } |
256 } |
376 |
257 |
377 final var projectDao = dao.getProjectDao(); |
|
378 final var versionDao = dao.getVersionDao(); |
|
379 final var issueDao = dao.getIssueDao(); |
258 final var issueDao = dao.getIssueDao(); |
380 |
259 |
381 final var viewModel = new ProjectView(selection.project); |
260 final var project = viewModel.getProjectInfo().getProject(); |
382 final var issues = issueDao.list(selection.project); |
261 |
|
262 final var detailView = viewModel.getProjectDetails(); |
|
263 if (viewModel.getVersionFilter() != null) { |
|
264 detailView.updateVersionInfo(List.of(viewModel.getVersionFilter())); |
|
265 } else { |
|
266 detailView.updateVersionInfo(viewModel.getProjectInfo().getVersions()); |
|
267 } |
|
268 final var issues = issueDao.list(project); |
383 for (var issue : issues) issueDao.joinVersionInformation(issue); |
269 for (var issue : issues) issueDao.joinVersionInformation(issue); |
384 viewModel.setIssues(issues); |
270 detailView.setIssues(issues); |
385 // TODO: fix duplicated selection of versions (projectInfo also contains these infos) |
271 |
386 viewModel.setVersions(versionDao.list(selection.project)); |
272 return forwardView(req, viewModel, "project-details"); |
387 viewModel.updateVersionInfo(); |
|
388 setViewModel(req, viewModel); |
|
389 |
|
390 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
|
391 setContentPage(req, "project-details"); |
|
392 setStylesheet(req, "projects"); |
|
393 |
|
394 return ResponseType.HTML; |
|
395 } |
|
396 |
|
397 @RequestMapping(requestPath = "versions/view", method = HttpMethod.GET) |
|
398 public ResponseType viewVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
|
399 final var selection = new SessionSelection(req, dao); |
|
400 selection.sync(); |
|
401 if (selection.version == null) { |
|
402 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
|
403 return ResponseType.NONE; |
|
404 } |
|
405 |
|
406 final var projectDao = dao.getProjectDao(); |
|
407 final var issueDao = dao.getIssueDao(); |
|
408 |
|
409 final var viewModel = new VersionView(selection.version); |
|
410 final var issues = issueDao.list(selection.version); |
|
411 for (var issue : issues) issueDao.joinVersionInformation(issue); |
|
412 viewModel.setIssues(issues); |
|
413 setViewModel(req, viewModel); |
|
414 |
|
415 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
|
416 setContentPage(req, "version"); |
|
417 setStylesheet(req, "projects"); |
|
418 |
|
419 return ResponseType.HTML; |
|
420 } |
|
421 |
|
422 private VersionEditView configureEditVersionForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
|
423 final var viewModel = new VersionEditView(selection.version); |
|
424 if (selection.version.getProject() == null) { |
|
425 viewModel.setProjects(dao.getProjectDao().list()); |
|
426 } |
|
427 setViewModel(req, viewModel); |
|
428 setContentPage(req, "version-form"); |
|
429 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
|
430 return viewModel; |
|
431 } |
273 } |
432 |
274 |
433 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
275 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) |
434 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
276 public ResponseType editVersion(HttpServletRequest req, DataAccessObjects dao) throws SQLException { |
435 final var selection = new SessionSelection(req, dao); |
277 final var viewModel = new VersionEditView(); |
436 if (getParameter(req, Integer.class, "vid").isEmpty()) { |
278 populate(viewModel, req, dao); |
437 selection.newVersion(); |
279 |
|
280 if (viewModel.getVersionFilter() == null) { |
|
281 viewModel.setVersion(new Version(-1)); |
438 } else { |
282 } else { |
439 selection.sync(); |
283 viewModel.setVersion(viewModel.getVersionFilter()); |
440 } |
284 } |
441 |
285 |
442 configureEditVersionForm(req, dao, selection); |
286 return forwardView(req, viewModel, "version-form"); |
443 |
|
444 return ResponseType.HTML; |
|
445 } |
287 } |
446 |
288 |
447 @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST) |
289 @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST) |
448 public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
290 public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
449 |
291 |
460 setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId()); |
302 setRedirectLocation(req, "./projects/view?pid=" + version.getProject().getId()); |
461 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
303 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
462 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
304 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { |
463 LOG.warn("Form validation failure: {}", ex.getMessage()); |
305 LOG.warn("Form validation failure: {}", ex.getMessage()); |
464 LOG.debug("Details:", ex); |
306 LOG.debug("Details:", ex); |
465 final var selection = new SessionSelection(req, dao); |
307 final var viewModel = new VersionEditView(); |
466 selection.selectVersion(version); |
308 populate(viewModel, req, dao); |
467 final var viewModel = configureEditVersionForm(req, dao, selection); |
309 viewModel.setVersion(version); |
468 // TODO: set Error Text |
310 // TODO: set Error Text |
|
311 return forwardView(req, viewModel, "version-form"); |
469 } |
312 } |
470 |
313 |
471 return ResponseType.HTML; |
314 return ResponseType.HTML; |
472 } |
315 } |
473 |
316 |
474 private IssueEditView configureEditIssueForm(HttpServletRequest req, DataAccessObjects dao, SessionSelection selection) throws SQLException { |
317 private void configure(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException { |
475 final var viewModel = new IssueEditView(selection.issue); |
318 issue.setProject(viewModel.getProjectInfo().getProject()); |
476 |
319 viewModel.setIssue(issue); |
477 if (selection.issue.getProject() == null) { |
320 viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); |
478 viewModel.setProjects(dao.getProjectDao().list()); |
|
479 } else { |
|
480 viewModel.setVersions(dao.getVersionDao().list(selection.issue.getProject())); |
|
481 } |
|
482 viewModel.setUsers(dao.getUserDao().list()); |
321 viewModel.setUsers(dao.getUserDao().list()); |
483 setViewModel(req, viewModel); |
|
484 |
|
485 setContentPage(req, "issue-form"); |
|
486 setNavigationMenu(req, getNavMenu(dao.getProjectDao().list(), selection, currentProjectInfo(dao, selection.project))); |
|
487 return viewModel; |
|
488 } |
|
489 |
|
490 @RequestMapping(requestPath = "issues/", method = HttpMethod.GET) |
|
491 public ResponseType issues(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { |
|
492 final var selection = new SessionSelection(req, dao); |
|
493 selection.sync(); |
|
494 if (selection.project == null) { |
|
495 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); |
|
496 return ResponseType.NONE; |
|
497 } |
|
498 |
|
499 final var projectDao = dao.getProjectDao(); |
|
500 final var issueDao = dao.getIssueDao(); |
|
501 |
|
502 final var viewModel = new IssuesView(); |
|
503 viewModel.setProject(selection.project); |
|
504 if (selection.version == null) { |
|
505 viewModel.setIssues(issueDao.list(selection.project)); |
|
506 } else { |
|
507 viewModel.setVersion(selection.version); |
|
508 viewModel.setIssues(issueDao.list(selection.version)); |
|
509 } |
|
510 setViewModel(req, viewModel); |
|
511 |
|
512 setNavigationMenu(req, getNavMenu(projectDao.list(), selection, currentProjectInfo(dao, selection.project))); |
|
513 setContentPage(req, "issues"); |
|
514 setStylesheet(req, "projects"); |
|
515 |
|
516 return ResponseType.HTML; |
|
517 } |
322 } |
518 |
323 |
519 @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET) |
324 @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET) |
520 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
325 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
521 final var selection = new SessionSelection(req, dao); |
326 final var viewModel = new IssueEditView(); |
522 if (getParameter(req, Integer.class, "issue").isEmpty()) { |
327 |
523 selection.newIssue(); |
328 final var issueParam = getParameter(req, Integer.class, "issue"); |
|
329 if (issueParam.isPresent()) { |
|
330 final var issue = dao.getIssueDao().find(issueParam.get()); |
|
331 req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, issue.getProject().getId()); |
|
332 populate(viewModel, req, dao); |
|
333 configure(viewModel, issue, dao); |
524 } else { |
334 } else { |
525 selection.sync(); |
335 populate(viewModel, req, dao); |
526 } |
336 configure(viewModel, new Issue(-1), dao); |
527 |
337 } |
528 configureEditIssueForm(req, dao, selection); |
338 |
529 |
339 return forwardView(req, viewModel, "issue-form"); |
530 return ResponseType.HTML; |
|
531 } |
340 } |
532 |
341 |
533 @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST) |
342 @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST) |
534 public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
343 public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { |
535 |
|
536 Issue issue = new Issue(-1); |
344 Issue issue = new Issue(-1); |
537 try { |
345 try { |
538 issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); |
346 issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); |
539 issue.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow())); |
347 issue.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow())); |
540 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); |
348 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); |