70 } catch (NumberFormatException ex) { |
76 } catch (NumberFormatException ex) { |
71 return 0; |
77 return 0; |
72 } |
78 } |
73 } |
79 } |
74 |
80 |
75 private void populate(ProjectView viewModel, PathParameters pathParameters, DaoProvider dao) { |
81 private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObject dao) { |
76 final var projectDao = dao.getProjectDao(); |
82 dao.listProjects().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); |
77 final var versionDao = dao.getVersionDao(); |
|
78 final var componentDao = dao.getComponentDao(); |
|
79 |
|
80 projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); |
|
81 |
83 |
82 if (pathParameters == null) |
84 if (pathParameters == null) |
83 return; |
85 return; |
84 |
86 |
85 // Select Project |
87 // Select Project |
86 final var project = projectDao.findByNode(pathParameters.get("project")); |
88 final var project = dao.findProjectByNode(pathParameters.get("project")); |
87 if (project == null) |
89 if (project == null) |
88 return; |
90 return; |
89 |
91 |
90 final var info = new ProjectInfo(project); |
92 final var info = new ProjectInfo(project); |
91 info.setVersions(versionDao.list(project)); |
93 info.setVersions(dao.listVersions(project)); |
92 info.setComponents(componentDao.list(project)); |
94 info.setComponents(dao.listComponents(project)); |
93 info.setIssueSummary(projectDao.getIssueSummary(project)); |
95 info.setIssueSummary(dao.collectIssueSummary(project)); |
94 viewModel.setProjectInfo(info); |
96 viewModel.setProjectInfo(info); |
95 |
97 |
96 // Select Version |
98 // Select Version |
97 final var versionNode = pathParameters.get("version"); |
99 final var versionNode = pathParameters.get("version"); |
98 if (versionNode != null) { |
100 if (versionNode != null) { |
99 if ("no-version".equals(versionNode)) { |
101 if ("no-version".equals(versionNode)) { |
100 viewModel.setVersionFilter(ProjectView.NO_VERSION); |
102 viewModel.setVersionFilter(ProjectView.NO_VERSION); |
101 } else if ("all-versions".equals(versionNode)) { |
103 } else if ("all-versions".equals(versionNode)) { |
102 viewModel.setVersionFilter(ProjectView.ALL_VERSIONS); |
104 viewModel.setVersionFilter(ProjectView.ALL_VERSIONS); |
103 } else { |
105 } else { |
104 viewModel.setVersionFilter(versionDao.findByNode(project, versionNode)); |
106 viewModel.setVersionFilter(dao.findVersionByNode(project, versionNode)); |
105 } |
107 } |
106 } |
108 } |
107 |
109 |
108 // Select Component |
110 // Select Component |
109 final var componentNode = pathParameters.get("component"); |
111 final var componentNode = pathParameters.get("component"); |
135 setNavigationMenu(req, "project-navmenu"); |
137 setNavigationMenu(req, "project-navmenu"); |
136 renderSite(req, resp); |
138 renderSite(req, resp); |
137 } |
139 } |
138 |
140 |
139 @RequestMapping(method = HttpMethod.GET) |
141 @RequestMapping(method = HttpMethod.GET) |
140 public void index(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { |
142 public void index(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws ServletException, IOException { |
141 final var viewModel = new ProjectView(); |
143 final var viewModel = new ProjectView(); |
142 populate(viewModel, null, dao); |
144 populate(viewModel, null, dao); |
143 |
145 |
144 final var projectDao = dao.getProjectDao(); |
|
145 final var versionDao = dao.getVersionDao(); |
|
146 |
|
147 for (var info : viewModel.getProjectList()) { |
146 for (var info : viewModel.getProjectList()) { |
148 info.setVersions(versionDao.list(info.getProject())); |
147 info.setVersions(dao.listVersions(info.getProject())); |
149 info.setIssueSummary(projectDao.getIssueSummary(info.getProject())); |
148 info.setIssueSummary(dao.collectIssueSummary(info.getProject())); |
150 } |
149 } |
151 |
150 |
152 forwardView(req, resp, viewModel, "projects"); |
151 forwardView(req, resp, viewModel, "projects"); |
153 } |
152 } |
154 |
153 |
155 private void configureProjectEditor(ProjectEditView viewModel, Project project, DaoProvider dao) throws SQLException { |
154 private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObject dao) { |
156 viewModel.setProject(project); |
155 viewModel.setProject(project); |
157 viewModel.setUsers(dao.getUserDao().list()); |
156 viewModel.setUsers(dao.listUsers()); |
158 } |
157 } |
159 |
158 |
160 @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET) |
159 @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET) |
161 public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DaoProvider dao) throws IOException, SQLException, ServletException { |
160 public void edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObject dao) throws IOException, SQLException, ServletException { |
162 final var viewModel = new ProjectEditView(); |
161 final var viewModel = new ProjectEditView(); |
163 populate(viewModel, pathParams, dao); |
162 populate(viewModel, pathParams, dao); |
164 |
163 |
165 if (!viewModel.isProjectInfoPresent()) { |
164 if (!viewModel.isProjectInfoPresent()) { |
166 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
165 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
170 configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao); |
169 configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao); |
171 forwardView(req, resp, viewModel, "project-form"); |
170 forwardView(req, resp, viewModel, "project-form"); |
172 } |
171 } |
173 |
172 |
174 @RequestMapping(requestPath = "create", method = HttpMethod.GET) |
173 @RequestMapping(requestPath = "create", method = HttpMethod.GET) |
175 public void create(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws SQLException, ServletException, IOException { |
174 public void create(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws SQLException, ServletException, IOException { |
176 final var viewModel = new ProjectEditView(); |
175 final var viewModel = new ProjectEditView(); |
177 populate(viewModel, null, dao); |
176 populate(viewModel, null, dao); |
178 configureProjectEditor(viewModel, new Project(-1), dao); |
177 configureProjectEditor(viewModel, new Project(-1), dao); |
179 forwardView(req, resp, viewModel, "project-form"); |
178 forwardView(req, resp, viewModel, "project-form"); |
180 } |
179 } |
181 |
180 |
182 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) |
181 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) |
183 public void commit(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { |
182 public void commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { |
184 |
183 |
185 try { |
184 try { |
186 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); |
185 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); |
187 project.setName(getParameter(req, String.class, "name").orElseThrow()); |
186 project.setName(getParameter(req, String.class, "name").orElseThrow()); |
188 |
187 |
226 |
223 |
227 final var project = viewModel.getProjectInfo().getProject(); |
224 final var project = viewModel.getProjectInfo().getProject(); |
228 final var version = viewModel.getVersionFilter(); |
225 final var version = viewModel.getVersionFilter(); |
229 final var component = viewModel.getComponentFilter(); |
226 final var component = viewModel.getComponentFilter(); |
230 |
227 |
231 final var issueDao = dao.getIssueDao(); |
228 // TODO: use new IssueFilter class for the ViewModel |
232 |
229 |
233 final List<Issue> issues; |
230 final var projectFilter = new SpecificFilter<>(project); |
|
231 final IssueFilter filter; |
234 if (version.equals(ProjectView.NO_VERSION)) { |
232 if (version.equals(ProjectView.NO_VERSION)) { |
235 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
233 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
236 issues = issueDao.list(project, (Version) null); |
234 filter = new IssueFilter(projectFilter, |
|
235 new NoneFilter<>(), |
|
236 new AllFilter<>() |
|
237 ); |
237 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
238 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
238 issues = issueDao.list(project, null, null); |
239 filter = new IssueFilter(projectFilter, |
239 } else { |
240 new NoneFilter<>(), |
240 issues = issueDao.list(project, component, null); |
241 new NoneFilter<>() |
|
242 ); |
|
243 } else { |
|
244 filter = new IssueFilter(projectFilter, |
|
245 new NoneFilter<>(), |
|
246 new SpecificFilter<>(component) |
|
247 ); |
241 } |
248 } |
242 } else if (version.equals(ProjectView.ALL_VERSIONS)) { |
249 } else if (version.equals(ProjectView.ALL_VERSIONS)) { |
243 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
250 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
244 issues = issueDao.list(project); |
251 filter = new IssueFilter(projectFilter, |
|
252 new AllFilter<>(), |
|
253 new AllFilter<>() |
|
254 ); |
245 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
255 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
246 issues = issueDao.list(project, (Component)null); |
256 filter = new IssueFilter(projectFilter, |
247 } else { |
257 new AllFilter<>(), |
248 issues = issueDao.list(project, component); |
258 new NoneFilter<>() |
|
259 ); |
|
260 } else { |
|
261 filter = new IssueFilter(projectFilter, |
|
262 new AllFilter<>(), |
|
263 new SpecificFilter<>(component) |
|
264 ); |
249 } |
265 } |
250 } else { |
266 } else { |
251 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
267 if (component.equals(ProjectView.ALL_COMPONENTS)) { |
252 issues = issueDao.list(project, version); |
268 filter = new IssueFilter(projectFilter, |
|
269 new SpecificFilter<>(version), |
|
270 new AllFilter<>() |
|
271 ); |
253 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
272 } else if (component.equals(ProjectView.NO_COMPONENT)) { |
254 issues = issueDao.list(project, null, version); |
273 filter = new IssueFilter(projectFilter, |
255 } else { |
274 new SpecificFilter<>(version), |
256 issues = issueDao.list(project, component, version); |
275 new NoneFilter<>() |
257 } |
276 ); |
258 } |
277 } else { |
259 |
278 filter = new IssueFilter(projectFilter, |
260 for (var issue : issues) issueDao.joinVersionInformation(issue); |
279 new SpecificFilter<>(version), |
|
280 new SpecificFilter<>(component) |
|
281 ); |
|
282 } |
|
283 } |
|
284 |
|
285 final var issues = dao.listIssues(filter); |
261 issues.sort(new IssueSorter( |
286 issues.sort(new IssueSorter( |
262 new IssueSorter.Criteria(IssueSorter.Field.DONE, true), |
287 new IssueSorter.Criteria(IssueSorter.Field.DONE, true), |
263 new IssueSorter.Criteria(IssueSorter.Field.ETA, true), |
288 new IssueSorter.Criteria(IssueSorter.Field.ETA, true), |
264 new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false) |
289 new IssueSorter.Criteria(IssueSorter.Field.UPDATED, false) |
265 )); |
290 )); |
271 |
296 |
272 forwardView(req, resp, viewModel, "project-details"); |
297 forwardView(req, resp, viewModel, "project-details"); |
273 } |
298 } |
274 |
299 |
275 @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET) |
300 @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET) |
276 public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
301 public void versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { |
277 final var viewModel = new VersionsView(); |
302 final var viewModel = new VersionsView(); |
278 populate(viewModel, pathParameters, dao); |
303 populate(viewModel, pathParameters, dao); |
279 |
304 |
280 final var projectInfo = viewModel.getProjectInfo(); |
305 final var projectInfo = viewModel.getProjectInfo(); |
281 if (projectInfo == null) { |
306 if (projectInfo == null) { |
282 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
307 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
283 return; |
308 return; |
284 } |
309 } |
285 |
310 |
286 final var issueDao = dao.getIssueDao(); |
311 final var issues = dao.listIssues( |
287 final var issues = issueDao.list(projectInfo.getProject()); |
312 new IssueFilter( |
288 for (var issue : issues) issueDao.joinVersionInformation(issue); |
313 new SpecificFilter<>(projectInfo.getProject()), |
|
314 new AllFilter<>(), |
|
315 new AllFilter<>() |
|
316 ) |
|
317 ); |
289 viewModel.update(projectInfo.getVersions(), issues); |
318 viewModel.update(projectInfo.getVersions(), issues); |
290 |
319 |
291 forwardView(req, resp, viewModel, "versions"); |
320 forwardView(req, resp, viewModel, "versions"); |
292 } |
321 } |
293 |
322 |
294 @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET) |
323 @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET) |
295 public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
324 public void editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { |
296 final var viewModel = new VersionEditView(); |
325 final var viewModel = new VersionEditView(); |
297 populate(viewModel, pathParameters, dao); |
326 populate(viewModel, pathParameters, dao); |
298 |
327 |
299 if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) { |
328 if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) { |
300 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
329 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
305 |
334 |
306 forwardView(req, resp, viewModel, "version-form"); |
335 forwardView(req, resp, viewModel, "version-form"); |
307 } |
336 } |
308 |
337 |
309 @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET) |
338 @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET) |
310 public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
339 public void createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { |
311 final var viewModel = new VersionEditView(); |
340 final var viewModel = new VersionEditView(); |
312 populate(viewModel, pathParameters, dao); |
341 populate(viewModel, pathParameters, dao); |
313 |
342 |
314 if (viewModel.getProjectInfo() == null) { |
343 if (viewModel.getProjectInfo() == null) { |
315 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
344 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
316 return; |
345 return; |
317 } |
346 } |
318 |
347 |
319 viewModel.setVersion(new Version(-1)); |
348 viewModel.setVersion(new Version(-1, viewModel.getProjectInfo().getProject().getId())); |
320 |
349 |
321 forwardView(req, resp, viewModel, "version-form"); |
350 forwardView(req, resp, viewModel, "version-form"); |
322 } |
351 } |
323 |
352 |
324 @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST) |
353 @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST) |
325 public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { |
354 public void commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { |
326 |
355 |
327 try { |
356 try { |
328 final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); |
357 final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); |
329 if (project == null) { |
358 if (project == null) { |
330 // TODO: improve error handling, because not found is not correct for this POST request |
359 // TODO: improve error handling, because not found is not correct for this POST request |
331 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
360 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
332 return; |
361 return; |
333 } |
362 } |
334 final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow()); |
363 final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow(), project.getId()); |
335 version.setName(getParameter(req, String.class, "name").orElseThrow()); |
364 version.setName(getParameter(req, String.class, "name").orElseThrow()); |
336 |
365 |
337 final var node = getParameter(req, String.class, "node").orElse(null); |
366 final var node = getParameter(req, String.class, "node").orElse(null); |
338 version.setNode(sanitizeNode(node, version.getName())); |
367 version.setNode(sanitizeNode(node, version.getName())); |
339 |
368 |
340 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); |
369 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); |
341 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); |
370 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); |
342 |
371 |
343 final var versionDao = dao.getVersionDao(); |
|
344 if (version.getId() > 0) { |
372 if (version.getId() > 0) { |
345 // TODO: use return value |
373 dao.updateVersion(version); |
346 versionDao.update(version); |
374 } else { |
347 } else { |
375 dao.insertVersion(version); |
348 versionDao.save(version, project); |
|
349 } |
376 } |
350 |
377 |
351 setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/"); |
378 setRedirectLocation(req, "./projects/" + project.getNode() + "/versions/"); |
352 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
379 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
353 |
380 |
357 // TODO: implement - fix issue #21 |
384 // TODO: implement - fix issue #21 |
358 } |
385 } |
359 } |
386 } |
360 |
387 |
361 @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET) |
388 @RequestMapping(requestPath = "$project/components/", method = HttpMethod.GET) |
362 public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
389 public void components(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { |
363 final var viewModel = new ComponentsView(); |
390 final var viewModel = new ComponentsView(); |
364 populate(viewModel, pathParameters, dao); |
391 populate(viewModel, pathParameters, dao); |
365 |
392 |
366 final var projectInfo = viewModel.getProjectInfo(); |
393 final var projectInfo = viewModel.getProjectInfo(); |
367 if (projectInfo == null) { |
394 if (projectInfo == null) { |
368 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
395 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
369 return; |
396 return; |
370 } |
397 } |
371 |
398 |
372 final var issueDao = dao.getIssueDao(); |
399 final var issues = dao.listIssues( |
373 final var issues = issueDao.list(projectInfo.getProject()); |
400 new IssueFilter( |
|
401 new SpecificFilter<>(projectInfo.getProject()), |
|
402 new AllFilter<>(), |
|
403 new AllFilter<>() |
|
404 ) |
|
405 ); |
374 viewModel.update(projectInfo.getComponents(), issues); |
406 viewModel.update(projectInfo.getComponents(), issues); |
375 |
407 |
376 forwardView(req, resp, viewModel, "components"); |
408 forwardView(req, resp, viewModel, "components"); |
377 } |
409 } |
378 |
410 |
379 @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET) |
411 @RequestMapping(requestPath = "$project/components/$component/edit", method = HttpMethod.GET) |
380 public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
412 public void editComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { |
381 final var viewModel = new ComponentEditView(); |
413 final var viewModel = new ComponentEditView(); |
382 populate(viewModel, pathParameters, dao); |
414 populate(viewModel, pathParameters, dao); |
383 |
415 |
384 if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) { |
416 if (viewModel.getProjectInfo() == null || viewModel.getComponentFilter() == null) { |
385 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
417 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
386 return; |
418 return; |
387 } |
419 } |
388 |
420 |
389 viewModel.setComponent(viewModel.getComponentFilter()); |
421 viewModel.setComponent(viewModel.getComponentFilter()); |
390 viewModel.setUsers(dao.getUserDao().list()); |
422 viewModel.setUsers(dao.listUsers()); |
391 |
423 |
392 forwardView(req, resp, viewModel, "component-form"); |
424 forwardView(req, resp, viewModel, "component-form"); |
393 } |
425 } |
394 |
426 |
395 @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET) |
427 @RequestMapping(requestPath = "$project/create-component", method = HttpMethod.GET) |
396 public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
428 public void createComponent(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { |
397 final var viewModel = new ComponentEditView(); |
429 final var viewModel = new ComponentEditView(); |
398 populate(viewModel, pathParameters, dao); |
430 populate(viewModel, pathParameters, dao); |
399 |
431 |
400 if (viewModel.getProjectInfo() == null) { |
432 if (viewModel.getProjectInfo() == null) { |
401 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
433 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
402 return; |
434 return; |
403 } |
435 } |
404 |
436 |
405 viewModel.setComponent(new Component(-1)); |
437 viewModel.setComponent(new Component(-1, viewModel.getProjectInfo().getProject().getId())); |
406 viewModel.setUsers(dao.getUserDao().list()); |
438 viewModel.setUsers(dao.listUsers()); |
407 |
439 |
408 forwardView(req, resp, viewModel, "component-form"); |
440 forwardView(req, resp, viewModel, "component-form"); |
409 } |
441 } |
410 |
442 |
411 @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST) |
443 @RequestMapping(requestPath = "commit-component", method = HttpMethod.POST) |
412 public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { |
444 public void commitComponent(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { |
413 |
445 |
414 try { |
446 try { |
415 final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); |
447 final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); |
416 if (project == null) { |
448 if (project == null) { |
417 // TODO: improve error handling, because not found is not correct for this POST request |
449 // TODO: improve error handling, because not found is not correct for this POST request |
418 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
450 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
419 return; |
451 return; |
420 } |
452 } |
421 final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow()); |
453 final var component = new Component(getParameter(req, Integer.class, "id").orElseThrow(), project.getId()); |
422 component.setName(getParameter(req, String.class, "name").orElseThrow()); |
454 component.setName(getParameter(req, String.class, "name").orElseThrow()); |
423 |
455 |
424 final var node = getParameter(req, String.class, "node").orElse(null); |
456 final var node = getParameter(req, String.class, "node").orElse(null); |
425 component.setNode(sanitizeNode(node, component.getName())); |
457 component.setNode(sanitizeNode(node, component.getName())); |
426 |
458 |
447 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); |
477 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED); |
448 // TODO: implement - fix issue #21 |
478 // TODO: implement - fix issue #21 |
449 } |
479 } |
450 } |
480 } |
451 |
481 |
452 private void configureIssueEditor(IssueEditView viewModel, Issue issue, DaoProvider dao) throws SQLException { |
482 private void configureIssueEditor(IssueEditView viewModel, Issue issue, DataAccessObject dao) { |
453 final var project = viewModel.getProjectInfo().getProject(); |
483 final var project = viewModel.getProjectInfo().getProject(); |
454 issue.setProject(project); // automatically set current project for new issues |
484 issue.setProject(project); // automatically set current project for new issues |
455 viewModel.setIssue(issue); |
485 viewModel.setIssue(issue); |
456 viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); |
486 viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); |
457 viewModel.setUsers(dao.getUserDao().list()); |
487 viewModel.setUsers(dao.listUsers()); |
458 viewModel.setComponents(dao.getComponentDao().list(project)); |
488 viewModel.setComponents(dao.listComponents(project)); |
459 } |
489 } |
460 |
490 |
461 @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET) |
491 @RequestMapping(requestPath = "$project/issues/$issue/view", method = HttpMethod.GET) |
462 public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
492 public void viewIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, ServletException { |
463 final var viewModel = new IssueDetailView(); |
493 final var viewModel = new IssueDetailView(); |
464 populate(viewModel, pathParameters, dao); |
494 populate(viewModel, pathParameters, dao); |
465 |
495 |
466 final var projectInfo = viewModel.getProjectInfo(); |
496 final var projectInfo = viewModel.getProjectInfo(); |
467 if (projectInfo == null) { |
497 if (projectInfo == null) { |
468 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
498 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
469 return; |
499 return; |
470 } |
500 } |
471 |
501 |
472 final var issueDao = dao.getIssueDao(); |
502 final var issue = dao.findIssue(parseIntOrZero(pathParameters.get("issue"))); |
473 final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); |
|
474 if (issue == null) { |
503 if (issue == null) { |
475 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
504 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
476 return; |
505 return; |
477 } |
506 } |
478 |
507 |
479 issueDao.joinVersionInformation(issue); |
|
480 viewModel.setIssue(issue); |
508 viewModel.setIssue(issue); |
481 viewModel.setComments(issueDao.listComments(issue)); |
509 viewModel.setComments(dao.listComments(issue)); |
482 |
510 |
483 viewModel.processMarkdown(); |
511 viewModel.processMarkdown(); |
484 |
512 |
485 forwardView(req, resp, viewModel, "issue-view"); |
513 forwardView(req, resp, viewModel, "issue-view"); |
486 } |
514 } |
487 |
515 |
488 // TODO: why should the issue editor be child of $project? |
516 // TODO: why should the issue editor be child of $project? |
489 @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET) |
517 @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET) |
490 public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
518 public void editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { |
491 final var viewModel = new IssueEditView(); |
519 final var viewModel = new IssueEditView(); |
492 populate(viewModel, pathParameters, dao); |
520 populate(viewModel, pathParameters, dao); |
493 |
521 |
494 final var projectInfo = viewModel.getProjectInfo(); |
522 final var projectInfo = viewModel.getProjectInfo(); |
495 if (projectInfo == null) { |
523 if (projectInfo == null) { |
496 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
524 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
497 return; |
525 return; |
498 } |
526 } |
499 |
527 |
500 final var issueDao = dao.getIssueDao(); |
528 final var issue = dao.findIssue(parseIntOrZero(pathParameters.get("issue"))); |
501 final var issue = issueDao.find(parseIntOrZero(pathParameters.get("issue"))); |
|
502 if (issue == null) { |
529 if (issue == null) { |
503 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
530 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
504 return; |
531 return; |
505 } |
532 } |
506 |
533 |
507 issueDao.joinVersionInformation(issue); |
|
508 configureIssueEditor(viewModel, issue, dao); |
534 configureIssueEditor(viewModel, issue, dao); |
509 |
535 |
510 forwardView(req, resp, viewModel, "issue-form"); |
536 forwardView(req, resp, viewModel, "issue-form"); |
511 } |
537 } |
512 |
538 |
513 @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET) |
539 @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET) |
514 public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DaoProvider dao) throws IOException, SQLException, ServletException { |
540 public void createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObject dao) throws IOException, SQLException, ServletException { |
515 final var viewModel = new IssueEditView(); |
541 final var viewModel = new IssueEditView(); |
516 populate(viewModel, pathParameters, dao); |
542 populate(viewModel, pathParameters, dao); |
517 |
543 |
518 final var projectInfo = viewModel.getProjectInfo(); |
544 final var projectInfo = viewModel.getProjectInfo(); |
519 if (projectInfo == null) { |
545 if (projectInfo == null) { |
520 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
546 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
521 return; |
547 return; |
522 } |
548 } |
523 |
549 |
524 final var issue = new Issue(-1); |
550 // TODO: fix #38 - automatically select component (and version) |
|
551 final var issue = new Issue(-1, projectInfo.getProject(), null); |
525 issue.setProject(projectInfo.getProject()); |
552 issue.setProject(projectInfo.getProject()); |
526 configureIssueEditor(viewModel, issue, dao); |
553 configureIssueEditor(viewModel, issue, dao); |
527 |
554 |
528 forwardView(req, resp, viewModel, "issue-form"); |
555 forwardView(req, resp, viewModel, "issue-form"); |
529 } |
556 } |
530 |
557 |
531 @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST) |
558 @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST) |
532 public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { |
559 public void commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { |
533 try { |
560 try { |
534 final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); |
561 final var project = dao.findProject(getParameter(req, Integer.class, "pid").orElseThrow()); |
535 final var componentId = getParameter(req, Integer.class, "component"); |
|
536 final Component component; |
|
537 if (componentId.isPresent()) { |
|
538 component = dao.getComponentDao().find(componentId.get()); |
|
539 } else { |
|
540 component = null; |
|
541 } |
|
542 final var project = dao.getProjectDao().find(getParameter(req, Integer.class, "pid").orElseThrow()); |
|
543 if (project == null) { |
562 if (project == null) { |
544 // TODO: improve error handling, because not found is not correct for this POST request |
563 // TODO: improve error handling, because not found is not correct for this POST request |
545 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
564 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
546 return; |
565 return; |
547 } |
566 } |
548 issue.setProject(project); |
567 final var componentId = getParameter(req, Integer.class, "component"); |
|
568 final Component component; |
|
569 if (componentId.isPresent()) { |
|
570 component = dao.findComponent(componentId.get()); |
|
571 } else { |
|
572 component = null; |
|
573 } |
|
574 final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow(), project, component); |
549 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); |
575 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); |
550 getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus); |
576 getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus); |
551 issue.setSubject(getParameter(req, String.class, "subject").orElseThrow()); |
577 issue.setSubject(getParameter(req, String.class, "subject").orElseThrow()); |
552 issue.setComponent(component); |
|
553 getParameter(req, Integer.class, "assignee").map(userid -> { |
578 getParameter(req, Integer.class, "assignee").map(userid -> { |
554 if (userid >= 0) { |
579 if (userid >= 0) { |
555 return new User(userid); |
580 return new User(userid); |
556 } else if (userid == -2) { |
581 } else if (userid == -2) { |
557 return Optional.ofNullable(component).map(Component::getLead).orElse(null); |
582 return Optional.ofNullable(component).map(Component::getLead).orElse(null); |
564 getParameter(req, Date.class, "eta").ifPresent(issue::setEta); |
589 getParameter(req, Date.class, "eta").ifPresent(issue::setEta); |
565 |
590 |
566 getParameter(req, Integer[].class, "affected") |
591 getParameter(req, Integer[].class, "affected") |
567 .map(Stream::of) |
592 .map(Stream::of) |
568 .map(stream -> |
593 .map(stream -> |
569 stream.map(Version::new).collect(Collectors.toList()) |
594 stream.map(id -> new Version(id, project.getId())) |
|
595 .collect(Collectors.toList()) |
570 ).ifPresent(issue::setAffectedVersions); |
596 ).ifPresent(issue::setAffectedVersions); |
571 getParameter(req, Integer[].class, "resolved") |
597 getParameter(req, Integer[].class, "resolved") |
572 .map(Stream::of) |
598 .map(Stream::of) |
573 .map(stream -> |
599 .map(stream -> |
574 stream.map(Version::new).collect(Collectors.toList()) |
600 stream.map(id -> new Version(id, project.getId())) |
|
601 .collect(Collectors.toList()) |
575 ).ifPresent(issue::setResolvedVersions); |
602 ).ifPresent(issue::setResolvedVersions); |
576 |
603 |
577 final var issueDao = dao.getIssueDao(); |
|
578 if (issue.getId() > 0) { |
604 if (issue.getId() > 0) { |
579 // TODO: use return value |
605 dao.updateIssue(issue); |
580 issueDao.update(issue); |
606 } else { |
581 } else { |
607 dao.insertIssue(issue); |
582 issueDao.save(issue, project); |
608 } |
583 } |
609 |
584 |
610 // TODO: implement #110 |
585 // TODO: fix redirect location |
|
586 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); |
611 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); |
587 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
612 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
588 |
613 |
589 renderSite(req, resp); |
614 renderSite(req, resp); |
590 } catch (NoSuchElementException | IllegalArgumentException ex) { |
615 } catch (NoSuchElementException | IllegalArgumentException ex) { |
592 // TODO: implement - fix issue #21 |
617 // TODO: implement - fix issue #21 |
593 } |
618 } |
594 } |
619 } |
595 |
620 |
596 @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST) |
621 @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST) |
597 public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DaoProvider dao) throws IOException, ServletException { |
622 public void commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObject dao) throws IOException, ServletException { |
598 final var issueIdParam = getParameter(req, Integer.class, "issueid"); |
623 final var issueIdParam = getParameter(req, Integer.class, "issueid"); |
599 if (issueIdParam.isEmpty()) { |
624 if (issueIdParam.isEmpty()) { |
600 resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form."); |
625 resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form."); |
601 return; |
626 return; |
602 } |
627 } |
603 final var issue = dao.getIssueDao().find(issueIdParam.get()); |
628 final var issue = dao.findIssue(issueIdParam.get()); |
604 if (issue == null) { |
629 if (issue == null) { |
605 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
630 resp.sendError(HttpServletResponse.SC_NOT_FOUND); |
606 return; |
631 return; |
607 } |
632 } |
608 try { |
633 try { |
609 final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1)); |
634 final var issueComment = new IssueComment(getParameter(req, Integer.class, "commentid").orElse(-1), issue.getId()); |
610 issueComment.setComment(getParameter(req, String.class, "comment").orElse("")); |
635 issueComment.setComment(getParameter(req, String.class, "comment").orElse("")); |
611 |
636 |
612 if (issueComment.getComment().isBlank()) { |
637 if (issueComment.getComment().isBlank()) { |
613 throw new IllegalArgumentException("comment.null"); |
638 throw new IllegalArgumentException("comment.null"); |
614 } |
639 } |
615 |
640 |
616 LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId()); |
641 LOG.debug("User {} is commenting on issue #{}", req.getRemoteUser(), issue.getId()); |
617 if (req.getRemoteUser() != null) { |
642 if (req.getRemoteUser() != null) { |
618 Optional.ofNullable(dao.getUserDao().findByUsername(req.getRemoteUser())).ifPresent(issueComment::setAuthor); |
643 Optional.ofNullable(dao.findUserByName(req.getRemoteUser())).ifPresent(issueComment::setAuthor); |
619 } |
644 } |
620 |
645 |
621 dao.getIssueDao().saveComment(issue, issueComment); |
646 dao.insertComment(issueComment); |
622 |
647 |
623 // TODO: fix redirect location |
|
624 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); |
648 setRedirectLocation(req, "./projects/" + issue.getProject().getNode()+"/issues/"+issue.getId()+"/view"); |
625 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
649 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); |
626 |
650 |
627 renderSite(req, resp); |
651 renderSite(req, resp); |
628 } catch (NoSuchElementException | IllegalArgumentException ex) { |
652 } catch (NoSuchElementException | IllegalArgumentException ex) { |