1 package org.itracker.web.actions.project;
2
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.Collections;
8 import java.util.Date;
9 import java.util.HashMap;
10 import java.util.HashSet;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Locale;
14 import java.util.Map;
15 import java.util.MissingResourceException;
16 import java.util.ResourceBundle;
17 import java.util.Set;
18
19 import javax.servlet.ServletException;
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpSession;
22
23 import org.apache.log4j.Logger;
24 import org.apache.struts.action.ActionForward;
25 import org.apache.struts.action.ActionMapping;
26 import org.apache.struts.action.ActionMessages;
27 import org.itracker.core.resources.ITrackerResources;
28 import org.itracker.model.Component;
29 import org.itracker.model.CustomField;
30 import org.itracker.model.Issue;
31 import org.itracker.model.IssueField;
32 import org.itracker.model.IssueHistory;
33 import org.itracker.model.IssueRelation;
34 import org.itracker.model.NameValuePair;
35 import org.itracker.model.Notification;
36 import org.itracker.model.PermissionType;
37 import org.itracker.model.Project;
38 import org.itracker.model.ProjectScript;
39 import org.itracker.model.Status;
40 import org.itracker.model.User;
41 import org.itracker.model.Version;
42 import org.itracker.model.Notification.Role;
43 import org.itracker.model.Notification.Type;
44 import org.itracker.services.IssueService;
45 import org.itracker.services.NotificationService;
46 import org.itracker.services.ProjectService;
47 import org.itracker.services.UserService;
48 import org.itracker.services.exceptions.WorkflowException;
49 import org.itracker.services.util.Convert;
50 import org.itracker.services.util.HTMLUtilities;
51 import org.itracker.services.util.IssueUtilities;
52 import org.itracker.services.util.NotificationUtilities;
53 import org.itracker.services.util.ProjectUtilities;
54 import org.itracker.services.util.UserUtilities;
55 import org.itracker.services.util.WorkflowUtilities;
56 import org.itracker.web.forms.IssueForm;
57 import org.itracker.web.util.AttachmentUtilities;
58 import org.itracker.web.util.Constants;
59 import org.itracker.web.util.LoginUtilities;
60 import org.itracker.web.util.ServletContextUtils;
61
62 public class EditIssueActionUtil {
63 private static final Logger log = Logger.getLogger(EditIssueActionUtil.class);
64
65 public static final Issue processFullEdit(Issue issue, Project project, User user,
66 Map<Integer, Set<PermissionType>> userPermissions, Locale locale,
67 IssueForm form, IssueService issueService, ActionMessages errors) throws Exception {
68 int previousStatus = issue.getStatus();
69 boolean needReloadIssue = false;
70 ActionMessages msg = new ActionMessages();
71 issue = AttachmentUtilities.addAttachment(issue, project, user, form, ServletContextUtils.getItrackerServices(), msg);
72
73 if (!msg.isEmpty()) {
74
75 errors.add(msg);
76 return issue;
77 }
78
79 needReloadIssue = issueService.setIssueVersions(issue.getId(),
80 new HashSet<Integer>(Arrays.asList(form.getVersions())),
81 user.getId());
82
83 needReloadIssue = needReloadIssue | issueService.setIssueComponents(issue.getId(),
84 new HashSet<Integer>(Arrays.asList(form.getComponents())),
85 user.getId());
86
87
88
89
90
91 if (needReloadIssue) {
92 if (log.isDebugEnabled()) {
93 log.debug("processFullEdit: updating issue from session: " + issue);
94 }
95 issue = issueService.getIssue(issue.getId());
96 }
97
98 Integer targetVersion = form.getTargetVersion();
99 if (targetVersion != null && targetVersion != -1) {
100 ProjectService projectService = ServletContextUtils.getItrackerServices()
101 .getProjectService();
102 Version version = projectService.getProjectVersion(targetVersion);
103 if (version == null) {
104 throw new RuntimeException("No version with Id "
105 + targetVersion);
106 }
107 issue.setTargetVersion(version);
108 }
109
110 issue.setResolution(form.getResolution());
111 issue.setSeverity(form.getSeverity());
112
113 applyLimitedFields(issue, project, user, userPermissions, locale, form, issueService);
114
115 Integer formStatus = form.getStatus();
116 issue.setStatus(formStatus);
117 if (formStatus != null) {
118 if (log.isDebugEnabled()) {
119 log.debug("processFullEdit: processing status: " + formStatus);
120 }
121 if (previousStatus != -1) {
122
123 if ((previousStatus >= IssueUtilities.STATUS_ASSIGNED && previousStatus < IssueUtilities.STATUS_RESOLVED)
124 && (previousStatus >= IssueUtilities.STATUS_RESOLVED && previousStatus < IssueUtilities.STATUS_END)) {
125 issue.setResolution("");
126 }
127
128 if (previousStatus >= IssueUtilities.STATUS_CLOSED
129 && !UserUtilities.hasPermission(userPermissions, project
130 .getId(), UserUtilities.PERMISSION_CLOSE)) {
131 if (previousStatus < IssueUtilities.STATUS_CLOSED) {
132 issue.setStatus(previousStatus);
133 } else {
134 issue.setStatus(IssueUtilities.STATUS_RESOLVED);
135 }
136 }
137
138 if (issue.getStatus() < IssueUtilities.STATUS_NEW
139 || issue.getStatus() >= IssueUtilities.STATUS_END) {
140 issue.setStatus(previousStatus);
141 }
142 } else if (issue.getStatus() >= IssueUtilities.STATUS_CLOSED
143 && !UserUtilities.hasPermission(userPermissions, project
144 .getId(), UserUtilities.PERMISSION_CLOSE)) {
145 issue.setStatus(IssueUtilities.STATUS_RESOLVED);
146 }
147 }
148
149 if (issue.getStatus() < IssueUtilities.STATUS_NEW) {
150 if (log.isDebugEnabled()) {
151 log.debug("processFullEdit: status < STATUS_NEW: " + issue.getStatus());
152 }
153 issue.setStatus(IssueUtilities.STATUS_NEW);
154 if (log.isDebugEnabled()) {
155 log.debug("processFullEdit: updated to: " + issue.getStatus());
156 }
157 } else if (issue.getStatus() >= IssueUtilities.STATUS_END) {
158 if (log.isDebugEnabled()) {
159 log.debug("processFullEdit: status >= STATUS_END: " + issue.getStatus());
160 }
161 if (!UserUtilities.hasPermission(userPermissions, project.getId(),
162 UserUtilities.PERMISSION_CLOSE)) {
163 issue.setStatus(IssueUtilities.STATUS_RESOLVED);
164 } else {
165 issue.setStatus(IssueUtilities.STATUS_CLOSED);
166 }
167 if (log.isDebugEnabled()) {
168 log.debug("processFullEdit: status updated to: " + issue.getStatus());
169 }
170 }
171 if (log.isDebugEnabled()) {
172 log.debug("processFullEdit: updating issue " + issue);
173 }
174 return issueService.updateIssue(issue, user.getId());
175 }
176
177 public static final void applyLimitedFields(Issue issue, Project project,
178 User user, Map<Integer, Set<PermissionType>> userPermissionsMap,
179 Locale locale, IssueForm form, IssueService issueService) throws Exception {
180
181 issue.setDescription(form.getDescription());
182
183 setIssueFields(issue, user, locale, form, issueService);
184 setOwner(issue, user, userPermissionsMap, form, issueService);
185 addHistoryEntry(issue, user, form, issueService);
186 }
187
188 private static void setIssueFields(Issue issue, User user, Locale locale,
189 IssueForm form, IssueService issueService) throws Exception {
190 if (log.isDebugEnabled()) {
191 log.debug("setIssueFields: called");
192 }
193 List<CustomField> projectCustomFields = issue.getProject()
194 .getCustomFields();
195 if (log.isDebugEnabled()) {
196 log.debug("setIssueFields: got project custom fields: " + projectCustomFields);
197 }
198
199 if (projectCustomFields == null || projectCustomFields.size() == 0) {
200 log.debug("setIssueFields: no custom fields, returning...");
201 return;
202 }
203
204
205
206
207 HashMap<String, String> formCustomFields = form.getCustomFields();
208
209 if (log.isDebugEnabled()) {
210 log.debug("setIssueFields: got form custom fields: " + formCustomFields);
211 }
212
213 if (formCustomFields == null || formCustomFields.size() == 0) {
214 log.debug("setIssueFields: no form custom fields, returning..");
215 return;
216 }
217
218 ResourceBundle bundle = ITrackerResources.getBundle(locale);
219
220 Iterator<CustomField> customFieldsIt = projectCustomFields.iterator();
221
222 CustomField field;
223 String fieldValue;
224 IssueField issueField;
225 try {
226 if (log.isDebugEnabled()) {
227 log.debug("setIssueFields: processing project fields");
228 }
229
230 while (customFieldsIt.hasNext()) {
231
232 field = customFieldsIt.next();
233 fieldValue = (String) formCustomFields.get(String.valueOf(field
234 .getId()));
235
236
237 issueField = getIssueField(issue, field);
238
239
240 if (fieldValue != null && fieldValue.trim().length() > 0) {
241 if (null == issueField) {
242 issueField = new IssueField(issue, field);
243 issue.getFields().add(issueField);
244 }
245
246 issueField.setValue(fieldValue, bundle);
247 } else {
248 if (null != issueField) {
249 issue.getFields().remove(issueField);
250 }
251 }
252 }
253
254
255
256
257
258 } catch (Exception e) {
259 log.error("setIssueFields: failed to process custom fields", e);
260 throw e;
261 }
262 }
263
264 private static IssueField getIssueField(Issue issue, CustomField field) {
265 Iterator<IssueField> it = issue.getFields().iterator();
266 IssueField issueField = null;
267 while (it.hasNext()) {
268 issueField = it.next();
269 if (issueField.getCustomField().equals(field)) {
270 return issueField;
271 }
272 }
273 return null;
274
275 }
276
277 private static void setOwner(Issue issue, User user,
278 Map<Integer, Set<PermissionType>> userPermissionsMap,
279 IssueForm form, IssueService issueService) throws Exception {
280 if (log.isDebugEnabled()) {
281 log.debug("setOwner: called to " + form.getOwnerId());
282 }
283 Integer currentOwner = (issue.getOwner() == null) ? null : issue
284 .getOwner().getId();
285
286 Integer ownerId = form.getOwnerId();
287
288 if (ownerId == null || ownerId.equals(currentOwner)) {
289 if (log.isDebugEnabled()) {
290 log.debug("setOwner: returning, existing owner is the same: " + issue.getOwner());
291 }
292 return;
293 }
294
295 if (UserUtilities.hasPermission(userPermissionsMap,
296 UserUtilities.PERMISSION_ASSIGN_OTHERS)
297 || (UserUtilities.hasPermission(userPermissionsMap,
298 UserUtilities.PERMISSION_ASSIGN_SELF) && user.getId()
299 .equals(ownerId))
300 || (UserUtilities.hasPermission(userPermissionsMap,
301 UserUtilities.PERMISSION_UNASSIGN_SELF)
302 && user.getId().equals(currentOwner) && ownerId
303 .intValue() == -1)) {
304 User newOwner = ServletContextUtils.getItrackerServices().getUserService().getUser(ownerId);
305 if (log.isDebugEnabled()) {
306 log.debug("setOwner: setting new owner " + newOwner + " to " + issue);
307 }
308 issue.setOwner(newOwner);
309
310 }
311
312 }
313
314 private static void addHistoryEntry(Issue issue, User user, IssueForm form,
315 IssueService issueService) throws Exception {
316 try {
317 String history = form.getHistory();
318
319 if (history == null || history.equals("")) {
320 if (log.isDebugEnabled()) {
321 log.debug("addHistoryEntry: skip history to " + issue);
322 }
323 return;
324 }
325
326
327 if (ProjectUtilities.hasOption(ProjectUtilities.OPTION_SURPRESS_HISTORY_HTML, issue.getProject().getOptions())) {
328 history = HTMLUtilities.removeMarkup(history);
329 } else if(ProjectUtilities.hasOption(ProjectUtilities.OPTION_LITERAL_HISTORY_HTML, issue.getProject().getOptions())) {
330 history = HTMLUtilities.escapeTags(history);
331 } else {
332 history = HTMLUtilities.newlinesToBreaks(history);
333 }
334
335
336 if (log.isDebugEnabled()) {
337 log.debug("addHistoryEntry: adding history to " + issue);
338 }
339 IssueHistory issueHistory = new IssueHistory(issue, user, history,
340 IssueUtilities.HISTORY_STATUS_AVAILABLE);
341
342 issueHistory.setDescription(((IssueForm) form).getHistory());
343 issueHistory.setCreateDate(new Date());
344
345 issueHistory.setLastModifiedDate(new Date());
346 issue.getHistory().add(issueHistory);
347
348
349
350
351
352 } catch (Exception e) {
353 log.error("addHistoryEntry: failed to add", e);
354 throw e;
355 }
356
357 if (log.isDebugEnabled()) {
358 log.debug("addHistoryEntry: added history for issue " + issue);
359 }
360 }
361
362 public static final Issue processLimitedEdit(Issue issue, Project project,
363 User user, Map<Integer, Set<PermissionType>> userPermissionsMap,
364 Locale locale, IssueForm form, IssueService issueService, ActionMessages messages)
365 throws Exception {
366 ActionMessages msg = new ActionMessages();
367 issue = AttachmentUtilities.addAttachment(issue, project, user, form, ServletContextUtils.getItrackerServices(), msg);
368
369 if (!msg.isEmpty()) {
370 messages.add(msg);
371 return issue;
372 }
373
374 Integer formStatus = form.getStatus();
375
376 if (formStatus != null) {
377
378 if (issue.getStatus() >= IssueUtilities.STATUS_RESOLVED
379 && formStatus >= IssueUtilities.STATUS_CLOSED
380 && UserUtilities.hasPermission(userPermissionsMap,
381 UserUtilities.PERMISSION_CLOSE)) {
382
383 issue.setStatus(formStatus);
384 }
385
386 }
387
388 EditIssueActionUtil.applyLimitedFields(issue, project, user, userPermissionsMap, locale, form, issueService);
389 return issueService.updateIssue(issue, user.getId());
390
391 }
392
393 public static final void sendNotification(Integer issueId, int previousStatus,
394 String baseURL, NotificationService notificationService) {
395 Type notificationType = Type.UPDATED;
396
397 Issue issue = ServletContextUtils.getItrackerServices().getIssueService().getIssue(issueId);
398
399 if ((previousStatus < IssueUtilities.STATUS_CLOSED)
400 && issue.getStatus() >= IssueUtilities.STATUS_CLOSED) {
401 notificationType = Type.CLOSED;
402 }
403
404 if (log.isDebugEnabled()) {
405 log.debug("notificationService: before send");
406 }
407 notificationService.sendNotification(issue, notificationType, baseURL);
408
409 if (log.isDebugEnabled()) {
410 log.debug("notificationService: after send");
411 }
412 }
413
414 public static final ActionForward getReturnForward(Issue issue, Project project,
415 IssueForm form, ActionMapping mapping) throws Exception {
416 if ("index".equals(form.getCaller())) {
417 log.info("EditIssueAction: Forward: index");
418 return mapping.findForward("index");
419 } else if ("viewissue".equals(form.getCaller()) && issue.getStatus() >= IssueUtilities.STATUS_CLOSED) {
420 log.info("EditIssueAction: Forward: viewissue");
421 return new ActionForward(mapping.findForward("viewissue").getPath()
422 + "?id=" + issue.getId());
423 } else {
424 log.info("EditIssueAction: Forward: listissues");
425 return new ActionForward(mapping.findForward("listissues")
426 .getPath()
427 + "?projectId=" + project.getId());
428 }
429 }
430
431
432
433
434
435
436 public static final void setupJspEnv(ActionMapping mapping,
437 IssueForm issueForm, HttpServletRequest request, Issue issue,
438 IssueService issueService, UserService userService,
439 Map<Integer, Set<PermissionType>> userPermissions,
440 Map<Integer, List<NameValuePair>> listOptions, ActionMessages errors)
441 throws ServletException, IOException, WorkflowException {
442
443 if (log.isDebugEnabled()) {
444 log.debug("setupJspEnv: for issue " + issue);
445 }
446
447 NotificationService notificationService = ServletContextUtils
448 .getItrackerServices().getNotificationService();
449 String pageTitleKey = "itracker.web.editissue.title";
450 String pageTitleArg = request.getParameter("id");
451 Locale locale = LoginUtilities.getCurrentLocale(request);
452 User um = LoginUtilities.getCurrentUser(request);
453 List<NameValuePair> statuses = WorkflowUtilities.getListOptions(
454 listOptions, IssueUtilities.FIELD_STATUS);
455 String statusName = IssueUtilities.getStatusName(issue.getStatus(),locale);
456 boolean hasFullEdit = UserUtilities.hasPermission(userPermissions,
457 issue.getProject().getId(), UserUtilities.PERMISSION_EDIT_FULL);
458 List<NameValuePair> resolutions = WorkflowUtilities.getListOptions(
459 listOptions, IssueUtilities.FIELD_RESOLUTION);
460 String severityName = IssueUtilities.getSeverityName(issue
461 .getSeverity(),locale);
462 List<NameValuePair> components = WorkflowUtilities.getListOptions(
463 listOptions, IssueUtilities.FIELD_COMPONENTS);
464 List<NameValuePair> versions = WorkflowUtilities.getListOptions(
465 listOptions, IssueUtilities.FIELD_VERSIONS);
466 List<NameValuePair> targetVersion = WorkflowUtilities.getListOptions(
467 listOptions, IssueUtilities.FIELD_TARGET_VERSION);
468 List<Component> issueComponents = issue.getComponents();
469 Collections.sort(issueComponents);
470 List<Version> issueVersions = issue.getVersions();
471 Collections.sort(issueVersions, new Version.VersionComparator());
472
473 setupProjectFieldsMapJspEnv(issue.getProject().getCustomFields(), issue.getFields(), request);
474
475 setupRelationsRequestEnv(issue.getRelations(), request);
476
477
478 request.setAttribute("pageTitleKey", pageTitleKey);
479 request.setAttribute("pageTitleArg", pageTitleArg);
480
481 request.getSession().setAttribute(Constants.LIST_OPTIONS_KEY,
482 listOptions);
483 request.setAttribute("targetVersions", targetVersion);
484 request.setAttribute("components", components);
485 request.setAttribute("versions", versions);
486 request.setAttribute("hasIssueNotification", !notificationService
487 .hasIssueNotification(issue, um.getId()));
488 request.setAttribute("hasEditIssuePermission", UserUtilities
489 .hasPermission(userPermissions, issue.getProject().getId(),
490 UserUtilities.PERMISSION_EDIT));
491 request.setAttribute("canCreateIssue",
492 issue.getProject().getStatus() == Status.ACTIVE
493 && UserUtilities.hasPermission(userPermissions, issue
494 .getProject().getId(),
495 UserUtilities.PERMISSION_CREATE));
496 request.setAttribute("issueComponents", issueComponents);
497 request.setAttribute("issueVersions",
498 issueVersions == null ? new ArrayList<Version>()
499 : issueVersions);
500 request.setAttribute("statuses", statuses);
501 request.setAttribute("statusName", statusName);
502 request.setAttribute("hasFullEdit", hasFullEdit);
503 request.setAttribute("resolutions", resolutions);
504 request.setAttribute("severityName", severityName);
505 request.setAttribute("hasPredefinedResolutionsOption", ProjectUtilities
506 .hasOption(ProjectUtilities.OPTION_PREDEFINED_RESOLUTIONS,
507 issue.getProject().getOptions()));
508 request.setAttribute("issueOwnerName",
509 (issue.getOwner() == null ? ITrackerResources.getString(
510 "itracker.web.generic.unassigned",locale)
511 : issue.getOwner().getFirstName() + " "
512 + issue.getOwner().getLastName()));
513 request.setAttribute("isStatusResolved",
514 issue.getStatus() >= IssueUtilities.STATUS_RESOLVED);
515
516
517 request.setAttribute("fieldSeverity", WorkflowUtilities.getListOptions(
518 listOptions, IssueUtilities.FIELD_SEVERITY));
519 request.setAttribute("possibleOwners", WorkflowUtilities
520 .getListOptions(listOptions, IssueUtilities.FIELD_OWNER));
521
522 request.setAttribute("hasNoViewAttachmentOption", ProjectUtilities
523 .hasOption(ProjectUtilities.OPTION_NO_ATTACHMENTS, issue
524 .getProject().getOptions()));
525
526 if (log.isDebugEnabled()) {
527 log.debug("setupJspEnv: options " + issue.getProject().getOptions() + ", hasNoViewAttachmentOption: " + request.getAttribute("hasNoViewAttachmentOption"));
528 }
529
530 setupNotificationsInRequest(request, issue, notificationService);
531
532
533 request.setAttribute(Constants.ISSUE_KEY, issue);
534 request.setAttribute("issueForm", issueForm);
535 request.setAttribute(Constants.PROJECT_KEY, issue.getProject());
536 List<IssueHistory> issueHistory = issueService.getIssueHistory(issue
537 .getId());
538 Collections.sort(issueHistory, IssueHistory.CREATE_DATE_COMPARATOR);
539 request.setAttribute("issueHistory", issueHistory);
540
541
542 }
543
544
545
546
547
548 protected static final void setupProjectFieldsMapJspEnv(List<CustomField> projectFields, Collection<IssueField> issueFields, HttpServletRequest request) {
549 Map<CustomField,String> projectFieldsMap = new HashMap<CustomField, String>();
550
551 if (projectFields != null && projectFields.size() > 0) {
552 Collections.sort(projectFields, CustomField.ID_COMPARATOR);
553
554 HashMap<String, String> fieldValues = new HashMap<String, String>();
555 Iterator<IssueField> issueFieldsIt = issueFields.iterator();
556 while (issueFieldsIt.hasNext()) {
557 IssueField issueField = (IssueField) issueFieldsIt.next();
558
559 if (issueField.getCustomField() != null
560 && issueField.getCustomField().getId() > 0) {
561 if (issueField.getCustomField().getFieldType() == CustomField.Type.DATE) {
562 Locale locale = LoginUtilities.getCurrentLocale(request);
563 String value = issueField.getValue(locale);
564 fieldValues.put(issueField.getCustomField().getId()
565 .toString(), value);
566 } else {
567 fieldValues.put(issueField.getCustomField().getId()
568 .toString(), issueField
569 .getStringValue());
570 }
571 }
572 }
573 Iterator<CustomField> fieldsIt = projectFields.iterator();
574 CustomField field;
575 while (fieldsIt.hasNext()) {
576
577 field = fieldsIt.next();
578
579 String fieldValue = fieldValues.get(String.valueOf(field
580 .getId()));
581 if (null == fieldValue) {
582 fieldValue = "";
583 }
584
585
586
587
588
589 projectFieldsMap.put(field, fieldValue);
590
591 }
592
593 request.setAttribute("projectFieldsMap", projectFieldsMap);
594 }
595 }
596
597
598 protected static final void setupRelationsRequestEnv(List<IssueRelation> relations, HttpServletRequest request) {
599 Collections.sort(relations, IssueRelation.LAST_MODIFIED_DATE_COMPARATOR);
600 request.setAttribute("issueRelations", relations);
601
602 }
603
604
605 public static final void setupNotificationsInRequest(
606 HttpServletRequest request, Issue issue,
607 NotificationService notificationService) {
608 List<Notification> notifications = notificationService
609 .getIssueNotifications(issue);
610
611 Collections.sort(notifications, Notification.TYPE_COMPARATOR);
612
613 request.setAttribute("notifications", notifications);
614 Map<User, Set<Role>> notificationMap = NotificationUtilities
615 .mappedRoles(notifications);
616 request.setAttribute("notificationMap", notificationMap);
617 request.setAttribute("notifiedUsers", notificationMap.keySet());
618 }
619
620 public static Map<Integer, List<NameValuePair>> getListOptions(
621 HttpServletRequest request, Issue issue,
622 List<NameValuePair> ownersList,
623 Map<Integer, Set<PermissionType>> userPermissions, Project project,
624 User currUser) {
625 Map<Integer, List<NameValuePair>> listOptions = new HashMap<Integer, List<NameValuePair>>();
626
627 Locale locale = (Locale) request.getSession().getAttribute(
628 Constants.LOCALE_KEY);
629
630 if (ownersList != null && ownersList.size() > 0) {
631 listOptions.put(IssueUtilities.FIELD_OWNER, ownersList);
632 }
633
634 boolean hasFullEdit = UserUtilities.hasPermission(userPermissions,
635 project.getId(), UserUtilities.PERMISSION_EDIT_FULL);
636
637 List<NameValuePair> allStatuses = IssueUtilities.getStatuses(locale);
638 List<NameValuePair> statusList = new ArrayList<NameValuePair>();
639
640 if (!hasFullEdit) {
641
642 if (issue.getStatus() >= IssueUtilities.STATUS_RESOLVED
643 && UserUtilities.hasPermission(userPermissions, project
644 .getId(), UserUtilities.PERMISSION_CLOSE)) {
645 for (int i = 0; i < allStatuses.size(); i++) {
646 int statusNumber = Integer.parseInt(allStatuses.get(i)
647 .getValue());
648 if (issue.getStatus() >= IssueUtilities.STATUS_CLOSED
649 && statusNumber >= IssueUtilities.STATUS_CLOSED) {
650 statusList.add(allStatuses.get(i));
651 } else if (issue.getStatus() >= IssueUtilities.STATUS_RESOLVED
652 && statusNumber >= IssueUtilities.STATUS_RESOLVED) {
653 statusList.add(allStatuses.get(i));
654 }
655 }
656 } else {
657
658 }
659
660 } else {
661
662 if (currUser.isSuperUser()) {
663 for (int i = 0; i < allStatuses.size(); i++) {
664 statusList.add(allStatuses.get(i));
665 }
666 } else if (issue.getStatus() >= IssueUtilities.STATUS_ASSIGNED
667 && issue.getStatus() < IssueUtilities.STATUS_RESOLVED) {
668 for (int i = 0; i < allStatuses.size(); i++) {
669 int statusNumber = Integer.parseInt(allStatuses.get(i)
670 .getValue());
671 if (statusNumber >= IssueUtilities.STATUS_ASSIGNED
672 && statusNumber < IssueUtilities.STATUS_CLOSED) {
673 statusList.add(allStatuses.get(i));
674 } else if (statusNumber >= IssueUtilities.STATUS_CLOSED
675 && ProjectUtilities
676 .hasOption(
677 ProjectUtilities.OPTION_ALLOW_ASSIGN_TO_CLOSE,
678 project.getOptions())
679 && UserUtilities.hasPermission(userPermissions,
680 project.getId(),
681 UserUtilities.PERMISSION_CLOSE)) {
682 statusList.add(allStatuses.get(i));
683 }
684 }
685 } else if (issue.getStatus() >= IssueUtilities.STATUS_RESOLVED
686 && issue.getStatus() < IssueUtilities.STATUS_CLOSED) {
687 for (int i = 0; i < allStatuses.size(); i++) {
688 int statusNumber = Integer.parseInt(allStatuses.get(i)
689 .getValue());
690 if (statusNumber >= IssueUtilities.STATUS_ASSIGNED
691 && statusNumber < IssueUtilities.STATUS_CLOSED) {
692 statusList.add(allStatuses.get(i));
693 } else if (statusNumber >= IssueUtilities.STATUS_CLOSED
694 && UserUtilities.hasPermission(userPermissions,
695 project.getId(),
696 UserUtilities.PERMISSION_CLOSE)) {
697 statusList.add(allStatuses.get(i));
698 }
699 }
700 } else if (issue.getStatus() >= IssueUtilities.STATUS_CLOSED) {
701 for (int i = 0; i < allStatuses.size(); i++) {
702 int statusNumber = Integer.parseInt(allStatuses.get(i)
703 .getValue());
704 if ((statusNumber >= IssueUtilities.STATUS_ASSIGNED && statusNumber < IssueUtilities.STATUS_RESOLVED)
705 || statusNumber >= IssueUtilities.STATUS_CLOSED) {
706 statusList.add(allStatuses.get(i));
707 }
708 }
709 } else {
710
711 }
712
713 }
714
715 Collections.sort(statusList, NameValuePair.VALUE_COMPARATOR);
716 listOptions.put(IssueUtilities.FIELD_STATUS, statusList);
717
718 List<NameValuePair> severities = IssueUtilities.getSeverities(locale);
719
720 Collections.sort(severities, NameValuePair.VALUE_COMPARATOR);
721 listOptions.put(IssueUtilities.FIELD_SEVERITY, severities);
722
723 List<NameValuePair> resolutions = IssueUtilities.getResolutions(locale);
724 listOptions.put(IssueUtilities.FIELD_RESOLUTION, resolutions);
725
726 List<Component> components = project.getComponents();
727 Collections.sort(components, Component.NAME_COMPARATOR);
728 listOptions.put(IssueUtilities.FIELD_COMPONENTS, Convert
729 .componentsToNameValuePairs(components));
730
731 List<Version> versions = project.getVersions();
732
733 listOptions.put(IssueUtilities.FIELD_VERSIONS, Convert
734 .versionsToNameValuePairs(versions));
735 listOptions.put(IssueUtilities.FIELD_TARGET_VERSION, Convert
736 .versionsToNameValuePairs(versions));
737
738 List<CustomField> projectFields = project.getCustomFields();
739 for (int i = 0; i < projectFields.size(); i++) {
740 if (projectFields.get(i).getFieldType() == CustomField.Type.LIST) {
741
742 listOptions.put(projectFields.get(i).getId(), Convert
743 .customFieldOptionsToNameValuePairs(projectFields
744 .get(i).getOptions()));
745 }
746 }
747
748 return listOptions;
749 }
750
751 public static final void setupIssueForm(IssueForm issueForm, Issue issue,
752 Map<Integer, List<NameValuePair>> listOptions,
753 HttpServletRequest request, ActionMessages errors)
754 throws WorkflowException {
755 HttpSession session = request.getSession(true);
756
757 IssueService issueService = ServletContextUtils.getItrackerServices()
758 .getIssueService();
759 Locale locale = (Locale) session.getAttribute(Constants.LOCALE_KEY);
760 issueForm.setId(issue.getId());
761 issueForm.setProjectId(issue.getProject().getId());
762 issueForm.setPrevStatus(issue.getStatus());
763 issueForm.setCaller(request.getParameter("caller"));
764
765 issueForm.setDescription(HTMLUtilities.handleQuotes(issue
766 .getDescription()));
767 issueForm.setStatus(issue.getStatus());
768
769 if (!ProjectUtilities.hasOption(
770 ProjectUtilities.OPTION_PREDEFINED_RESOLUTIONS, issue
771 .getProject().getOptions())) {
772 try {
773 issue.setResolution(IssueUtilities.checkResolutionName(issue
774 .getResolution(), locale));
775 } catch (MissingResourceException mre) {
776 log.error(mre.getMessage());
777 } catch (NumberFormatException nfe) {
778 log.error(nfe.getMessage());
779 }
780 }
781
782 issueForm.setResolution(HTMLUtilities.handleQuotes(issue
783 .getResolution()));
784 issueForm.setSeverity(issue.getSeverity());
785
786 issueForm.setTargetVersion(issue.getTargetVersion() == null ? -1
787 : issue.getTargetVersion().getId());
788
789 issueForm.setOwnerId((issue.getOwner() == null ? -1 : issue.getOwner()
790 .getId()));
791
792 List<IssueField> fields = issue.getFields();
793 HashMap<String, String> customFields = new HashMap<String, String>();
794 for (int i = 0; i < fields.size(); i++) {
795 customFields.put(fields.get(i).getCustomField().getId().toString(),
796 fields.get(i).getValue(locale));
797 }
798
799 issueForm.setCustomFields(customFields);
800
801 HashSet<Integer> selectedComponents = issueService
802 .getIssueComponentIds(issue.getId());
803 if (selectedComponents != null) {
804 Integer[] componentIds = null;
805 ArrayList<Integer> components = new ArrayList<Integer>(
806 selectedComponents);
807 componentIds = components.toArray(new Integer[] {});
808 issueForm.setComponents(componentIds);
809 }
810
811 HashSet<Integer> selectedVersions = issueService
812 .getIssueVersionIds(issue.getId());
813 if (selectedVersions != null) {
814 Integer[] versionIds = null;
815 ArrayList<Integer> versions = new ArrayList<Integer>(
816 selectedVersions);
817 versionIds = versions.toArray(new Integer[] {});
818 issueForm.setVersions(versionIds);
819 }
820
821 List<ProjectScript> scripts = issue.getProject().getScripts();
822 WorkflowUtilities.processFieldScripts(scripts,
823 WorkflowUtilities.EVENT_FIELD_ONPOPULATE, listOptions, errors,
824 issueForm);
825 WorkflowUtilities.processFieldScripts(scripts,
826 WorkflowUtilities.EVENT_FIELD_ONSETDEFAULT, null, errors,
827 issueForm);
828
829 }
830
831 }