1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.itracker.web.actions.project;
20
21 import java.io.IOException;
22 import java.util.Date;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Map;
26 import java.util.ResourceBundle;
27 import java.util.Set;
28
29 import javax.servlet.ServletException;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpServletResponse;
32 import javax.servlet.http.HttpSession;
33
34 import org.apache.log4j.Level;
35 import org.apache.log4j.Logger;
36 import org.apache.struts.action.ActionForm;
37 import org.apache.struts.action.ActionForward;
38 import org.apache.struts.action.ActionMapping;
39 import org.apache.struts.action.ActionMessage;
40 import org.apache.struts.action.ActionMessages;
41 import org.apache.struts.validator.ValidatorForm;
42 import org.itracker.core.resources.ITrackerResources;
43 import org.itracker.model.CustomField;
44 import org.itracker.model.Issue;
45 import org.itracker.model.PermissionType;
46 import org.itracker.model.Project;
47 import org.itracker.model.ProjectScript;
48 import org.itracker.model.Status;
49 import org.itracker.model.User;
50 import org.itracker.services.IssueService;
51 import org.itracker.services.NotificationService;
52 import org.itracker.services.exceptions.IssueException;
53 import org.itracker.services.util.CustomFieldUtilities;
54 import org.itracker.services.util.IssueUtilities;
55 import org.itracker.services.util.UserUtilities;
56 import org.itracker.services.util.WorkflowUtilities;
57 import org.itracker.web.actions.base.ItrackerBaseAction;
58 import org.itracker.web.forms.IssueForm;
59 import org.itracker.web.util.Constants;
60
61 public class EditIssueAction extends ItrackerBaseAction {
62 private static final Logger log = Logger.getLogger(EditIssueAction.class);
63
64 public ActionForward execute(ActionMapping mapping, ActionForm form,
65 HttpServletRequest request, HttpServletResponse response)
66 throws ServletException, IOException {
67 log.info("execute: called");
68 ActionMessages errors = new ActionMessages();
69 Date logDate = new Date();
70 Date startDate = new Date();
71 logTimeMillies("execute: called", logDate, log, Level.DEBUG);
72
73 if (!isTokenValid(request)) {
74 log.debug("execute: Invalid request token while editing issue.");
75
76 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
77 "itracker.web.error.transaction"));
78 saveErrors(request, errors);
79 log.info("execute: return to edit-issue");
80 saveToken(request);
81
82 return mapping.getInputForward();
83 }
84 resetToken(request);
85
86
87 try {
88 IssueService issueService = getITrackerServices().getIssueService();
89 if (((IssueForm)form).getId() != null) {
90 Issue issue = getITrackerServices().getIssueService().getIssue((((IssueForm)form).getId()));
91 List<CustomField> projectFields = issue.getProject().getCustomFields();
92 if (projectFields.size() > 0) {
93 HttpSession session = request.getSession();
94 Locale locale = ITrackerResources.getLocale();
95 if (session != null) {
96 locale = (Locale) session.getAttribute(Constants.LOCALE_KEY);
97 }
98
99 ResourceBundle bundle = ITrackerResources.getBundle(locale);
100
101 for (int i = 0; i < projectFields.size(); i++) {
102 CustomField customField = projectFields.get(i);
103 String fieldValue = ((IssueForm)form).getCustomFields().get(String.valueOf(customField.getId()));
104
105
106 if (fieldValue != null && !fieldValue.equals("")) {
107 try {
108 customField.checkAssignable(fieldValue, locale, bundle);
109 } catch (IssueException ie) {
110 String label = CustomFieldUtilities.getCustomFieldName(
111 projectFields.get(i).getId(), locale);
112 errors.add(ActionMessages.GLOBAL_MESSAGE,
113 new ActionMessage(ie.getType(), label));
114 }
115 } else if (projectFields.get(i).isRequired()) {
116 String label = CustomFieldUtilities.getCustomFieldName(
117 projectFields.get(i).getId(), locale);
118 errors.add(ActionMessages.GLOBAL_MESSAGE,
119 new ActionMessage(IssueException.TYPE_CF_REQ_FIELD,
120 label));
121 }
122 }
123 }
124 if (!errors.isEmpty()) {
125 saveErrors(request, errors);
126 log.info("execute: return to edit-issue");
127 saveToken(request);
128 return mapping.getInputForward();
129 }
130 }
131
132 logTimeMillies("execute: got issueService", logDate, log, Level.DEBUG);
133 NotificationService notificationService = getITrackerServices()
134 .getNotificationService();
135 HttpSession session = request.getSession(true);
136 User currUser = (User) session.getAttribute(Constants.USER_KEY);
137
138 Map<Integer, Set<PermissionType>> userPermissions = getUserPermissions(session);
139
140 Integer currUserId = currUser.getId();
141 IssueForm issueForm = (IssueForm) form;
142 int previousStatus = -1;
143 Issue issue = issueService.getIssue(issueForm.getId());
144 logTimeMillies("execute: got issue", logDate, log, Level.DEBUG);
145
146 if (issue == null) {
147 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
148 "itracker.web.error.invalidissue"));
149 log.info("execute: invalidissue " + issueForm.getId() + ", Forward: Error");
150 return mapping.findForward("error");
151 }
152
153 Project project = issue.getProject();
154 logTimeMillies("execute: got project", logDate, log, Level.DEBUG);
155 if (project == null) {
156 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
157 "itracker.web.error.invalidproject"));
158 log.info("execute: Forward: Error");
159 return mapping.findForward("error");
160 } else if (project.getStatus() != Status.ACTIVE) {
161 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
162 "itracker.web.error.projectlocked"));
163 log.info("execute: Forward: Error");
164 return mapping.findForward("error");
165 } else if (!IssueUtilities.canEditIssue(issue, currUserId,
166 userPermissions)) {
167 log.info("execute: Forward: unauthorized");
168 return mapping.findForward("unauthorized");
169 }
170
171 List<ProjectScript> scripts = project.getScripts();
172 logTimeMillies("execute: got scripts", logDate, log, Level.DEBUG);
173 WorkflowUtilities.processFieldScripts(scripts,
174 WorkflowUtilities.EVENT_FIELD_ONPRESUBMIT, null, errors,
175 (ValidatorForm) form);
176 logTimeMillies("execute: processed field scripts EVENT_FIELD_ONPRESUBMIT", logDate, log, Level.DEBUG);
177
178 if (errors.isEmpty()) {
179 previousStatus = issue.getStatus();
180 try {
181 if (UserUtilities.hasPermission(userPermissions, project.getId(),
182 UserUtilities.PERMISSION_EDIT_FULL)) {
183 if (log.isDebugEnabled()) {
184 log.debug("execute: process full, " + issue);
185 }
186 issue = EditIssueActionUtil.processFullEdit(issue, project, currUser, userPermissions,
187 getLocale(request), issueForm, issueService, errors);
188 logTimeMillies("execute: processed fulledit", logDate, log, Level.DEBUG);
189 } else {
190 if (log.isDebugEnabled()) {
191 log.debug("execute: process limited, " + issue);
192 }
193 issue = EditIssueActionUtil.processLimitedEdit(issue, project, currUser, userPermissions,
194 getLocale(request), issueForm, issueService, errors);
195 logTimeMillies("execute: processed limited edit", logDate, log, Level.DEBUG);
196 }
197 } catch (Exception e) {
198 log.warn("execute: failed to update " + issue, e);
199 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("itracker.web.error.other"));
200 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(e.getMessage(), false));
201 }
202 }
203
204 if (errors.isEmpty()) {
205 if (log.isDebugEnabled()) {
206 log.debug("execute: sending notification for issue: " + issue
207 + " (HISTORIES: " + issueService.getIssueHistory(issue.getId()) + ")");
208 }
209 EditIssueActionUtil.sendNotification(issue.getId(), previousStatus,
210 getBaseURL(request), notificationService);
211 logTimeMillies("execute: sent notification", logDate, log, Level.DEBUG);
212
213 WorkflowUtilities.processFieldScripts(scripts,
214 WorkflowUtilities.EVENT_FIELD_ONPOSTSUBMIT, null, errors,
215 (ValidatorForm) form);
216 logTimeMillies("execute: processed field scripts EVENT_FIELD_ONPOSTSUBMIT", logDate, log, Level.DEBUG);
217
218 return EditIssueActionUtil.getReturnForward(issue, project, issueForm, mapping);
219 }
220 } catch (Exception e) {
221 log.error("execute: Exception processing form data", e);
222 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
223 "itracker.web.error.system"));
224 } finally {
225 logTimeMillies("execute: processed", startDate, log, Level.DEBUG);
226 }
227
228 if (!errors.isEmpty()) {
229 saveMessages(request, errors);
230 saveErrors(request, errors);
231 saveToken(request);
232
233 return mapping.getInputForward();
234
235 }
236
237 log.info("execute: Forward: Error");
238 return mapping.findForward("error");
239 }
240
241 }