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

changeset 131
67df332e3146
parent 129
a09d5c59351a
child 133
ef075cd7ce55
equal deleted inserted replaced
130:7ef369744fd1 131:67df332e3146
42 import javax.servlet.http.HttpServletResponse; 42 import javax.servlet.http.HttpServletResponse;
43 import java.io.IOException; 43 import java.io.IOException;
44 import java.sql.Date; 44 import java.sql.Date;
45 import java.sql.SQLException; 45 import java.sql.SQLException;
46 import java.util.NoSuchElementException; 46 import java.util.NoSuchElementException;
47 import java.util.Optional;
48 import java.util.stream.Collectors; 47 import java.util.stream.Collectors;
49 import java.util.stream.Stream; 48 import java.util.stream.Stream;
50
51 import static de.uapcore.lightpit.Functions.fqn;
52 49
53 @WebServlet( 50 @WebServlet(
54 name = "ProjectsModule", 51 name = "ProjectsModule",
55 urlPatterns = "/projects/*" 52 urlPatterns = "/projects/*"
56 ) 53 )
57 public final class ProjectsModule extends AbstractLightPITServlet { 54 public final class ProjectsModule extends AbstractLightPITServlet {
58 55
59 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class); 56 private static final Logger LOG = LoggerFactory.getLogger(ProjectsModule.class);
60 57
61 private static final String SESSION_ATTR_SELECTED_PROJECT = fqn(ProjectsModule.class, "selected_project");
62 private static final String SESSION_ATTR_SELECTED_VERSION = fqn(ProjectsModule.class, "selected_version");
63 private static final String SESSION_ATTR_SELECTED_COMPONENT = fqn(ProjectsModule.class, "selected_component");
64 private static final String PARAMETER_SELECTED_PROJECT = "pid";
65 private static final String PARAMETER_SELECTED_VERSION = "vid";
66 private static final String PARAMETER_SELECTED_COMPONENT = "cid";
67
68 @Override 58 @Override
69 protected String getResourceBundleName() { 59 protected String getResourceBundleName() {
70 return "localization.projects"; 60 return "localization.projects";
71 } 61 }
72 62
73 private int syncParamWithSession(HttpServletRequest req, String param, String attr) { 63 private void populate(ProjectView viewModel, PathParameters pathParameters, DataAccessObjects dao) throws SQLException {
74 final var session = req.getSession();
75 final var idParam = getParameter(req, Integer.class, param);
76 final int id;
77 if (idParam.isPresent()) {
78 id = idParam.get();
79 session.setAttribute(attr, id);
80 } else {
81 id = Optional.ofNullable(session.getAttribute(attr)).map(x->(Integer)x).orElse(-1);
82 }
83 return id;
84 }
85
86 private void populate(ProjectView viewModel, HttpServletRequest req, DataAccessObjects dao) throws SQLException {
87 final var projectDao = dao.getProjectDao(); 64 final var projectDao = dao.getProjectDao();
88 final var versionDao = dao.getVersionDao(); 65 final var versionDao = dao.getVersionDao();
89 final var componentDao = dao.getComponentDao(); 66 final var componentDao = dao.getComponentDao();
90 67
91 projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add); 68 projectDao.list().stream().map(ProjectInfo::new).forEach(viewModel.getProjectList()::add);
92 69
70 if (pathParameters == null)
71 return;
72
93 // Select Project 73 // Select Project
94 final int pid = syncParamWithSession(req, PARAMETER_SELECTED_PROJECT, SESSION_ATTR_SELECTED_PROJECT); 74 final int pid = Functions.parseIntOrZero(pathParameters.get("project"));
95 if (pid >= 0) { 75 if (pid > 0) {
96 final var project = projectDao.find(pid); 76 final var project = projectDao.find(pid);
97 if (project == null) { 77 if (project != null) {
98 req.setAttribute(SESSION_ATTR_SELECTED_PROJECT, -1);
99 } else {
100 final var info = new ProjectInfo(project); 78 final var info = new ProjectInfo(project);
101 info.setVersions(versionDao.list(project)); 79 info.setVersions(versionDao.list(project));
102 info.setComponents(componentDao.list(project)); 80 info.setComponents(componentDao.list(project));
103 info.setIssueSummary(projectDao.getIssueSummary(project)); 81 info.setIssueSummary(projectDao.getIssueSummary(project));
104 viewModel.setProjectInfo(info); 82 viewModel.setProjectInfo(info);
105 } 83 }
106 } 84 }
107 85
108 // Select Version 86 // Select Version
109 final int vid = syncParamWithSession(req, PARAMETER_SELECTED_VERSION, SESSION_ATTR_SELECTED_VERSION); 87 final int vid = Functions.parseIntOrZero(pathParameters.get("version"));
110 if (vid > 0) { 88 if (vid > 0) {
111 viewModel.setVersionFilter(versionDao.find(vid)); 89 viewModel.setVersionFilter(versionDao.find(vid));
112 } else { 90 }
113 // NULL for version means: show all unassigned 91 // TODO: don't treat unknown == unassigned - send 404 for unknown and introduce special word for unassigned
114 viewModel.setVersionFilter(null);
115 }
116 92
117 // Select Component 93 // Select Component
118 final int cid = syncParamWithSession(req, PARAMETER_SELECTED_COMPONENT, SESSION_ATTR_SELECTED_COMPONENT); 94 final int cid = Functions.parseIntOrZero(pathParameters.get("component"));
119 if (cid > 0) { 95 if (cid > 0) {
120 viewModel.setComponentFilter(componentDao.find(cid)); 96 viewModel.setComponentFilter(componentDao.find(cid));
121 } else if (cid <= 0) { 97 }
122 // -1 means: filter for unassigned, null means: show all 98
123 viewModel.setComponentFilter(new Component(-1)); 99 // TODO: distinguish all/unassigned for components
124 }
125 } 100 }
126 101
127 private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) { 102 private ResponseType forwardView(HttpServletRequest req, ProjectView viewModel, String name) {
128 setViewModel(req, viewModel); 103 setViewModel(req, viewModel);
129 setContentPage(req, name); 104 setContentPage(req, name);
133 } 108 }
134 109
135 @RequestMapping(method = HttpMethod.GET) 110 @RequestMapping(method = HttpMethod.GET)
136 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 111 public ResponseType index(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
137 final var viewModel = new ProjectView(); 112 final var viewModel = new ProjectView();
138 populate(viewModel, req, dao); 113 populate(viewModel, null, dao);
139 114
140 final var projectDao = dao.getProjectDao(); 115 final var projectDao = dao.getProjectDao();
141 final var versionDao = dao.getVersionDao(); 116 final var versionDao = dao.getVersionDao();
142 117
143 for (var info : viewModel.getProjectList()) { 118 for (var info : viewModel.getProjectList()) {
146 } 121 }
147 122
148 return forwardView(req, viewModel, "projects"); 123 return forwardView(req, viewModel, "projects");
149 } 124 }
150 125
151 private void configure(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException { 126 private void configureProjectEditor(ProjectEditView viewModel, Project project, DataAccessObjects dao) throws SQLException {
152 viewModel.setProject(project); 127 viewModel.setProject(project);
153 viewModel.setUsers(dao.getUserDao().list()); 128 viewModel.setUsers(dao.getUserDao().list());
154 } 129 }
155 130
156 @RequestMapping(requestPath = "edit", method = HttpMethod.GET) 131 @RequestMapping(requestPath = "$project/edit", method = HttpMethod.GET)
157 public ResponseType edit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 132 public ResponseType edit(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws IOException, SQLException {
158 final var viewModel = new ProjectEditView(); 133 final var viewModel = new ProjectEditView();
159 populate(viewModel, req, dao); 134 populate(viewModel, pathParams, dao);
160 135
161 final var project = Optional.ofNullable(viewModel.getProjectInfo()) 136 if (viewModel.getProjectInfo() == null) {
162 .map(ProjectInfo::getProject) 137 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
163 .orElse(new Project(-1)); 138 return ResponseType.NONE;
164 configure(viewModel, project, dao); 139 }
165 140
141 configureProjectEditor(viewModel, viewModel.getProjectInfo().getProject(), dao);
166 return forwardView(req, viewModel, "project-form"); 142 return forwardView(req, viewModel, "project-form");
167 } 143 }
168 144
145 @RequestMapping(requestPath = "create", method = HttpMethod.GET)
146 public ResponseType create(HttpServletRequest req, DataAccessObjects dao) throws SQLException {
147 final var viewModel = new ProjectEditView();
148 populate(viewModel, null, dao);
149 configureProjectEditor(viewModel, new Project(-1), dao);
150 return forwardView(req, viewModel, "project-form");
151 }
152
169 @RequestMapping(requestPath = "commit", method = HttpMethod.POST) 153 @RequestMapping(requestPath = "commit", method = HttpMethod.POST)
170 public ResponseType commit(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 154 public ResponseType commit(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException {
171 155
172 Project project = new Project(-1);
173 try { 156 try {
174 project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); 157 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
175 project.setName(getParameter(req, String.class, "name").orElseThrow()); 158 project.setName(getParameter(req, String.class, "name").orElseThrow());
176 getParameter(req, String.class, "description").ifPresent(project::setDescription); 159 getParameter(req, String.class, "description").ifPresent(project::setDescription);
177 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl); 160 getParameter(req, String.class, "repoUrl").ifPresent(project::setRepoUrl);
178 getParameter(req, Integer.class, "owner").map( 161 getParameter(req, Integer.class, "owner").map(
179 ownerId -> ownerId >= 0 ? new User(ownerId) : null 162 ownerId -> ownerId >= 0 ? new User(ownerId) : null
185 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 168 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
186 LOG.debug("Successfully updated project {}", project.getName()); 169 LOG.debug("Successfully updated project {}", project.getName());
187 170
188 return ResponseType.HTML; 171 return ResponseType.HTML;
189 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 172 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
190 LOG.warn("Form validation failure: {}", ex.getMessage()); 173 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
191 LOG.debug("Details:", ex); 174 // TODO: implement - fix issue #21
192 final var viewModel = new ProjectEditView(); 175 return ResponseType.NONE;
193 populate(viewModel, req, dao); 176 }
194 configure(viewModel, project, dao); 177 }
195 // TODO: error text 178
196 return forwardView(req, viewModel, "project-form"); 179 @RequestMapping(requestPath = "$project/versions/$version", method = HttpMethod.GET)
197 } 180 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParams, DataAccessObjects dao) throws SQLException, IOException {
198 }
199
200 @RequestMapping(requestPath = "view", method = HttpMethod.GET)
201 public ResponseType view(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
202 final var viewModel = new ProjectDetailsView(); 181 final var viewModel = new ProjectDetailsView();
203 populate(viewModel, req, dao); 182 populate(viewModel, pathParams, dao);
204 183 final var version = viewModel.getVersionFilter();
205 if (viewModel.getProjectInfo() == null) { 184
206 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); 185 if (viewModel.getProjectInfo() == null || version == null) {
186 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
207 return ResponseType.NONE; 187 return ResponseType.NONE;
208 } 188 }
209 189
210 final var issueDao = dao.getIssueDao(); 190 final var issueDao = dao.getIssueDao();
211
212 final var version = viewModel.getVersionFilter();
213 191
214 final var detailView = viewModel.getProjectDetails(); 192 final var detailView = viewModel.getProjectDetails();
215 final var issues = issueDao.list(version); 193 final var issues = issueDao.list(version);
216 for (var issue : issues) issueDao.joinVersionInformation(issue); 194 for (var issue : issues) issueDao.joinVersionInformation(issue);
217 issues.sort(new IssueSorter( 195 issues.sort(new IssueSorter(
222 detailView.updateDetails(issues, version); 200 detailView.updateDetails(issues, version);
223 201
224 return forwardView(req, viewModel, "project-details"); 202 return forwardView(req, viewModel, "project-details");
225 } 203 }
226 204
227 @RequestMapping(requestPath = "versions", method = HttpMethod.GET) 205 @RequestMapping(requestPath = "$project/versions/", method = HttpMethod.GET)
228 public ResponseType versions(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException { 206 public ResponseType versions(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException {
229 final var viewModel = new VersionsView(); 207 final var viewModel = new VersionsView();
230 populate(viewModel, req, dao); 208 populate(viewModel, pathParameters, dao);
231 viewModel.setVersionFilter(null);
232 209
233 final var projectInfo = viewModel.getProjectInfo(); 210 final var projectInfo = viewModel.getProjectInfo();
234 if (projectInfo == null) { 211 if (projectInfo == null) {
235 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); 212 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
236 return ResponseType.NONE; 213 return ResponseType.NONE;
237 } 214 }
238 215
239 final var issueDao = dao.getIssueDao(); 216 final var issueDao = dao.getIssueDao();
240 final var issues = issueDao.list(projectInfo.getProject()); 217 final var issues = issueDao.list(projectInfo.getProject());
242 viewModel.update(projectInfo.getVersions(), issues); 219 viewModel.update(projectInfo.getVersions(), issues);
243 220
244 return forwardView(req, viewModel, "versions"); 221 return forwardView(req, viewModel, "versions");
245 } 222 }
246 223
247 @RequestMapping(requestPath = "versions/edit", method = HttpMethod.GET) 224 @RequestMapping(requestPath = "$project/versions/$version/edit", method = HttpMethod.GET)
248 public ResponseType editVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException, SQLException { 225 public ResponseType editVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException {
249 final var viewModel = new VersionEditView(); 226 final var viewModel = new VersionEditView();
250 populate(viewModel, req, dao); 227 populate(viewModel, pathParameters, dao);
228
229 if (viewModel.getProjectInfo() == null || viewModel.getVersionFilter() == null) {
230 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
231 return ResponseType.NONE;
232 }
233
234 viewModel.setVersion(viewModel.getVersionFilter());
235
236 return forwardView(req, viewModel, "version-form");
237 }
238
239 @RequestMapping(requestPath = "$project/create-version", method = HttpMethod.GET)
240 public ResponseType createVersion(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException {
241 final var viewModel = new VersionEditView();
242 populate(viewModel, pathParameters, dao);
251 243
252 if (viewModel.getProjectInfo() == null) { 244 if (viewModel.getProjectInfo() == null) {
253 resp.sendError(HttpServletResponse.SC_NOT_FOUND, "No project selected."); 245 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
254 return ResponseType.NONE; 246 return ResponseType.NONE;
255 } 247 }
256 248
257 viewModel.setVersion(Optional.ofNullable(viewModel.getVersionFilter()).orElse(new Version(-1))); 249 viewModel.setVersion(viewModel.getVersionFilter());
258 250
259 return forwardView(req, viewModel, "version-form"); 251 return forwardView(req, viewModel, "version-form");
260 } 252 }
261 253
262 @RequestMapping(requestPath = "versions/commit", method = HttpMethod.POST) 254 @RequestMapping(requestPath = "commit-version", method = HttpMethod.POST)
263 public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { 255 public ResponseType commitVersion(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException {
264 256
265 var version = new Version(-1);
266 try { 257 try {
267 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow()); 258 final var project = new Project(getParameter(req, Integer.class, "pid").orElseThrow());
268 version = new Version(getParameter(req, Integer.class, "id").orElseThrow()); 259 final var version = new Version(getParameter(req, Integer.class, "id").orElseThrow());
269 version.setName(getParameter(req, String.class, "name").orElseThrow()); 260 version.setName(getParameter(req, String.class, "name").orElseThrow());
270 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal); 261 getParameter(req, Integer.class, "ordinal").ifPresent(version::setOrdinal);
271 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow())); 262 version.setStatus(VersionStatus.valueOf(getParameter(req, String.class, "status").orElseThrow()));
272 dao.getVersionDao().saveOrUpdate(version, project); 263 dao.getVersionDao().saveOrUpdate(version, project);
273 264
274 setRedirectLocation(req, "./projects/versions?pid=" + project.getId()); 265 // TODO: improve building the redirect location
266 setRedirectLocation(req, "./projects/" + project.getId() + "/versions/");
275 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 267 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
276 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 268 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
277 LOG.warn("Form validation failure: {}", ex.getMessage()); 269 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
278 LOG.debug("Details:", ex); 270 // TODO: implement - fix issue #21
279 final var viewModel = new VersionEditView(); 271 return ResponseType.NONE;
280 populate(viewModel, req, dao);
281 viewModel.setVersion(version);
282 // TODO: set Error Text
283 return forwardView(req, viewModel, "version-form");
284 } 272 }
285 273
286 return ResponseType.HTML; 274 return ResponseType.HTML;
287 } 275 }
288 276
289 private void configure(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException { 277 private void configureProjectEditor(IssueEditView viewModel, Issue issue, DataAccessObjects dao) throws SQLException {
290 issue.setProject(viewModel.getProjectInfo().getProject()); 278 issue.setProject(viewModel.getProjectInfo().getProject());
291 viewModel.setIssue(issue); 279 viewModel.setIssue(issue);
292 viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions()); 280 viewModel.configureVersionSelectors(viewModel.getProjectInfo().getVersions());
293 viewModel.setUsers(dao.getUserDao().list()); 281 viewModel.setUsers(dao.getUserDao().list());
294 if (issue.getId() >= 0) { 282 if (issue.getId() >= 0) {
295 viewModel.setComments(dao.getIssueDao().listComments(issue)); 283 viewModel.setComments(dao.getIssueDao().listComments(issue));
296 } 284 }
297 } 285 }
298 286
299 @RequestMapping(requestPath = "issues/edit", method = HttpMethod.GET) 287 @RequestMapping(requestPath = "$project/issues/$issue/edit", method = HttpMethod.GET)
300 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException { 288 public ResponseType editIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException {
301 final var viewModel = new IssueEditView(); 289 final var viewModel = new IssueEditView();
302 populate(viewModel, req, dao); 290 populate(viewModel, pathParameters, dao);
303 291
304 final var issueParam = getParameter(req, Integer.class, "issue"); 292 final var projectInfo = viewModel.getProjectInfo();
305 if (issueParam.isPresent()) { 293 if (projectInfo == null) {
306 final var issueDao = dao.getIssueDao(); 294 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
307 final var issue = issueDao.find(issueParam.get()); 295 return ResponseType.NONE;
308 issueDao.joinVersionInformation(issue); 296 }
309 req.getSession().setAttribute(SESSION_ATTR_SELECTED_PROJECT, issue.getProject().getId()); 297
310 configure(viewModel, issue, dao); 298 final var issueDao = dao.getIssueDao();
311 } else { 299 final var issue = issueDao.find(Functions.parseIntOrZero(pathParameters.get("issue")));
312 configure(viewModel, new Issue(-1), dao); 300 if (issue == null) {
313 } 301 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
302 return ResponseType.NONE;
303 }
304
305 issueDao.joinVersionInformation(issue);
306 configureProjectEditor(viewModel, issue, dao);
314 307
315 return forwardView(req, viewModel, "issue-form"); 308 return forwardView(req, viewModel, "issue-form");
316 } 309 }
317 310
318 @RequestMapping(requestPath = "issues/commit", method = HttpMethod.POST) 311 @RequestMapping(requestPath = "$project/create-issue", method = HttpMethod.GET)
319 public ResponseType commitIssue(HttpServletRequest req, DataAccessObjects dao) throws SQLException { 312 public ResponseType createIssue(HttpServletRequest req, HttpServletResponse resp, PathParameters pathParameters, DataAccessObjects dao) throws IOException, SQLException {
320 Issue issue = new Issue(-1); 313 final var viewModel = new IssueEditView();
314 populate(viewModel, pathParameters, dao);
315
316 final var projectInfo = viewModel.getProjectInfo();
317 if (projectInfo == null) {
318 resp.sendError(HttpServletResponse.SC_NOT_FOUND);
319 return ResponseType.NONE;
320 }
321
322 final var issue = new Issue(-1);
323 issue.setProject(projectInfo.getProject());
324 configureProjectEditor(viewModel, issue, dao);
325
326 return forwardView(req, viewModel, "issue-form");
327 }
328
329 @RequestMapping(requestPath = "commit-issue", method = HttpMethod.POST)
330 public ResponseType commitIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws IOException {
321 try { 331 try {
322 issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow()); 332 final var issue = new Issue(getParameter(req, Integer.class, "id").orElseThrow());
323 issue.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow())); 333 issue.setProject(new Project(getParameter(req, Integer.class, "pid").orElseThrow()));
324 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory); 334 getParameter(req, String.class, "category").map(IssueCategory::valueOf).ifPresent(issue::setCategory);
325 getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus); 335 getParameter(req, String.class, "status").map(IssueStatus::valueOf).ifPresent(issue::setStatus);
326 issue.setSubject(getParameter(req, String.class, "subject").orElseThrow()); 336 issue.setSubject(getParameter(req, String.class, "subject").orElseThrow());
327 getParameter(req, Integer.class, "assignee").map( 337 getParameter(req, Integer.class, "assignee").map(
341 stream.map(Version::new).collect(Collectors.toList()) 351 stream.map(Version::new).collect(Collectors.toList())
342 ).ifPresent(issue::setResolvedVersions); 352 ).ifPresent(issue::setResolvedVersions);
343 353
344 dao.getIssueDao().saveOrUpdate(issue, issue.getProject()); 354 dao.getIssueDao().saveOrUpdate(issue, issue.getProject());
345 355
346 // specifying the issue parameter keeps the edited issue as menu item 356 // TODO: fix issue #14
347 setRedirectLocation(req, "./projects/view?pid=" + issue.getProject().getId()); 357 setRedirectLocation(req, "./projects/" + issue.getProject().getId() + "/versions/");
348 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 358 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
349 359
350 return ResponseType.HTML; 360 return ResponseType.HTML;
351 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 361 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
352 // TODO: set request attribute with error text 362 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
353 LOG.warn("Form validation failure: {}", ex.getMessage()); 363 // TODO: implement - fix issue #21
354 LOG.debug("Details:", ex); 364 return ResponseType.NONE;
355 final var viewModel = new IssueEditView(); 365 }
356 populate(viewModel, req, dao); 366 }
357 configure(viewModel, issue, dao); 367
358 // TODO: set Error Text 368 @RequestMapping(requestPath = "commit-issue-comment", method = HttpMethod.POST)
359 return forwardView(req, viewModel, "issue-form");
360 }
361 }
362
363 @RequestMapping(requestPath = "issues/comment", method = HttpMethod.POST)
364 public ResponseType commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException { 369 public ResponseType commentIssue(HttpServletRequest req, HttpServletResponse resp, DataAccessObjects dao) throws SQLException, IOException {
365 final var issueIdParam = getParameter(req, Integer.class, "issueid"); 370 final var issueIdParam = getParameter(req, Integer.class, "issueid");
366 if (issueIdParam.isEmpty()) { 371 if (issueIdParam.isEmpty()) {
367 resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form."); 372 resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Detected manipulated form.");
368 return ResponseType.NONE; 373 return ResponseType.NONE;
381 dao.getUserDao().findByUsername(req.getRemoteUser()).ifPresent(issueComment::setAuthor); 386 dao.getUserDao().findByUsername(req.getRemoteUser()).ifPresent(issueComment::setAuthor);
382 } 387 }
383 388
384 dao.getIssueDao().saveComment(issueComment); 389 dao.getIssueDao().saveComment(issueComment);
385 390
386 // specifying the issue parameter keeps the edited issue as menu item 391 // TODO: fix redirect location (e.g. after fixing #24)
387 setRedirectLocation(req, "./projects/issues/edit?issue=" + issue.getId()); 392 setRedirectLocation(req, "./projects/" + issue.getProject().getId()+"/issues/"+issue.getId()+"/edit");
388 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL); 393 setContentPage(req, Constants.JSP_COMMIT_SUCCESSFUL);
389 394
390 return ResponseType.HTML; 395 return ResponseType.HTML;
391 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) { 396 } catch (NoSuchElementException | IllegalArgumentException | SQLException ex) {
392 // TODO: set request attribute with error text 397 resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
393 LOG.warn("Form validation failure: {}", ex.getMessage()); 398 // TODO: implement - fix issue #21
394 LOG.debug("Details:", ex); 399 return ResponseType.NONE;
395 final var viewModel = new IssueEditView();
396 populate(viewModel, req, dao);
397 configure(viewModel, issue, dao);
398 // TODO: set Error Text
399 return forwardView(req, viewModel, "issue-form");
400 } 400 }
401 } 401 }
402 } 402 }

mercurial