1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.itracker.web.forms;
20
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.ResourceBundle;
26
27 import javax.servlet.http.HttpServletRequest;
28 import javax.servlet.http.HttpSession;
29
30 import org.apache.log4j.Logger;
31 import org.apache.struts.action.ActionErrors;
32 import org.apache.struts.action.ActionMapping;
33 import org.apache.struts.action.ActionMessage;
34 import org.apache.struts.action.ActionMessages;
35 import org.apache.struts.upload.FormFile;
36 import org.itracker.core.resources.ITrackerResources;
37 import org.itracker.model.CustomField;
38 import org.itracker.model.Issue;
39 import org.itracker.model.NameValuePair;
40 import org.itracker.model.Project;
41 import org.itracker.model.ProjectScript;
42 import org.itracker.model.Status;
43 import org.itracker.model.User;
44 import org.itracker.services.ITrackerServices;
45 import org.itracker.services.exceptions.IssueException;
46 import org.itracker.services.exceptions.WorkflowException;
47 import org.itracker.services.util.CustomFieldUtilities;
48 import org.itracker.services.util.UserUtilities;
49 import org.itracker.services.util.WorkflowUtilities;
50 import org.itracker.web.actions.project.EditIssueActionUtil;
51 import org.itracker.web.ptos.CreateIssuePTO;
52 import org.itracker.web.util.AttachmentUtilities;
53 import org.itracker.web.util.Constants;
54 import org.itracker.web.util.RequestHelper;
55
56
57
58
59 public class IssueForm extends ITrackerForm {
60
61
62
63
64 private static final long serialVersionUID = 1L;
65
66 private static final Logger log = Logger.getLogger(IssueForm.class);
67
68 private Integer id = null;
69 private String caller = null;
70 private Integer projectId = null;
71 private Integer creatorId = null;
72 private Integer ownerId = null;
73 private String description = null;
74 private Integer severity = null;
75 private Integer status = null;
76 private Integer prevStatus = null;
77 private String resolution = null;
78 private Integer targetVersion = null;
79 private Integer[] components = new Integer[0];
80 private Integer[] versions = new Integer[0];
81 private String attachmentDescription = null;
82 transient private FormFile attachment = null;
83 private String history = null;
84
85 private HashMap<String, String> customFields = new HashMap<String, String>();
86 private Integer relationType = null;
87 private Integer relatedIssueId = null;
88
89 public FormFile getAttachment() {
90 return attachment;
91 }
92
93 public void setAttachment(FormFile attachment) {
94 this.attachment = attachment;
95 }
96
97 public String getAttachmentDescription() {
98 return attachmentDescription;
99 }
100
101 public void setAttachmentDescription(String attachmentDescription) {
102 this.attachmentDescription = attachmentDescription;
103 }
104
105 public String getCaller() {
106 return caller;
107 }
108
109 public void setCaller(String caller) {
110 this.caller = caller;
111 }
112
113 public Integer[] getComponents() {
114 if (null == components)
115 return null;
116 return components.clone();
117 }
118
119 public void setComponents(Integer[] components) {
120 if (null == components)
121 this.components = null;
122 else
123 this.components = components.clone();
124 }
125
126 public Integer getCreatorId() {
127 return creatorId;
128 }
129
130 public void setCreatorId(Integer creatorId) {
131 this.creatorId = creatorId;
132 }
133
134
135 public HashMap<String, String> getCustomFields() {
136 return customFields;
137 }
138
139
140 public void setCustomFields(HashMap<String, String> customFields) {
141 this.customFields = customFields;
142 }
143
144 public String getDescription() {
145 return description;
146 }
147
148 public void setDescription(String description) {
149 this.description = description;
150 }
151
152 public String getHistory() {
153 return history;
154 }
155
156 public void setHistory(String history) {
157 this.history = history;
158 }
159
160 public Integer getId() {
161 return id;
162 }
163
164 public void setId(Integer id) {
165 this.id = id;
166 }
167
168 public Integer getOwnerId() {
169 return ownerId;
170 }
171
172 public void setOwnerId(Integer ownerId) {
173 this.ownerId = ownerId;
174 }
175
176 public Integer getPrevStatus() {
177 return prevStatus;
178 }
179
180 public void setPrevStatus(Integer prevStatus) {
181 this.prevStatus = prevStatus;
182 }
183
184 public Integer getProjectId() {
185 return projectId;
186 }
187
188 public void setProjectId(Integer projectId) {
189 this.projectId = projectId;
190 }
191
192 public Integer getRelatedIssueId() {
193 return relatedIssueId;
194 }
195
196 public void setRelatedIssueId(Integer relatedIssueId) {
197 this.relatedIssueId = relatedIssueId;
198 }
199
200 public Integer getRelationType() {
201 return relationType;
202 }
203
204 public void setRelationType(Integer relationType) {
205 this.relationType = relationType;
206 }
207
208 public String getResolution() {
209 return resolution;
210 }
211
212 public void setResolution(String resolution) {
213 this.resolution = resolution;
214 }
215
216 public Integer getSeverity() {
217 return severity;
218 }
219
220 public void setSeverity(Integer severity) {
221 this.severity = severity;
222 }
223
224 public Integer getStatus() {
225 return status;
226 }
227
228 public void setStatus(Integer status) {
229 this.status = status;
230 }
231
232 public Integer getTargetVersion() {
233 return targetVersion;
234 }
235
236 public void setTargetVersion(Integer targetVersion) {
237 this.targetVersion = targetVersion;
238 }
239
240 public Integer[] getVersions() {
241 if (null == versions)
242 return null;
243 return versions.clone();
244 }
245
246 public void setVersions(Integer[] versions) {
247 if (null == versions)
248 this.versions = null;
249 else
250 this.versions = versions.clone();
251 }
252
253
254
255
256
257
258
259
260
261
262
263 public ActionErrors validate(ActionMapping mapping,
264 HttpServletRequest request) {
265 if (log.isDebugEnabled()) {
266 log.debug("validate called: mapping: " + mapping + ", request: "
267 + request);
268 }
269 ActionErrors errors = super.validate(mapping, request);
270
271 if (log.isDebugEnabled()) {
272 log.debug("validate called: mapping: " + mapping + ", request: "
273 + request + ", errors: " + errors);
274 }
275
276 try {
277 if (null != getId()) {
278 Issue issue = getITrackerServices().getIssueService().getIssue(
279 getId());
280
281 Locale locale = (Locale) request.getSession().getAttribute(
282 Constants.LOCALE_KEY);
283 User currUser = (User) request.getSession().getAttribute(
284 Constants.USER_KEY);
285 List<NameValuePair> ownersList = UserUtilities
286 .getAssignableIssueOwnersList(issue,
287 issue.getProject(), currUser, locale,
288 getITrackerServices().getUserService(),
289 RequestHelper.getUserPermissions(request
290 .getSession()));
291
292 EditIssueActionUtil.setupJspEnv(mapping, this, request, issue,
293 getITrackerServices().getIssueService(),
294 getITrackerServices().getUserService(), RequestHelper
295 .getUserPermissions(request.getSession()),
296 EditIssueActionUtil.getListOptions(request, issue,
297 ownersList, RequestHelper
298 .getUserPermissions(request
299 .getSession()), issue
300 .getProject(), currUser), errors);
301
302 if (errors.isEmpty() && issue.getProject() == null) {
303 if (log.isDebugEnabled()) {
304 log.debug("validate: issue project is null: " + issue);
305 }
306 errors.add(ActionMessages.GLOBAL_MESSAGE,
307 new ActionMessage(
308 "itracker.web.error.invalidproject"));
309 } else if (errors.isEmpty()
310 && issue.getProject().getStatus() != Status.ACTIVE) {
311 if (log.isDebugEnabled()) {
312 log.debug("validate: issue project is not active: " + issue);
313 }
314 errors.add(ActionMessages.GLOBAL_MESSAGE,
315 new ActionMessage(
316 "itracker.web.error.projectlocked"));
317 } else if (errors.isEmpty()) {
318 if (log.isDebugEnabled()) {
319 log.debug("validate: validation had errors for " + issue + ": " + errors);
320 }
321 validateProjectScripts(issue.getProject(), errors, this);
322 validateAttachment(this.getAttachment(), getITrackerServices(), errors);
323 }
324 } else {
325 CreateIssuePTO.setupCreateIssue(request);
326 HttpSession session = request.getSession();
327 Project project = (Project) session
328 .getAttribute(Constants.PROJECT_KEY);
329 if (log.isDebugEnabled()) {
330 log.debug("validate: validating create new issue for project: " + page);
331 }
332 validateProjectFields(project, request, errors);
333 validateProjectScripts(project, errors, this);
334 validateAttachment(this.getAttachment(), getITrackerServices(), errors);
335 }
336 } catch (Exception e) {
337 e.printStackTrace();
338 log.error("validate: unexpected exception", e);
339 errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
340 "itracker.web.error.system"));
341 }
342 if (log.isDebugEnabled()) {
343 log.debug("validate: returning errors: " + errors);
344 }
345 return errors;
346 }
347
348 private static void validateAttachment(FormFile attachment, ITrackerServices services, ActionMessages errors) {
349 if (null != attachment) {
350 ActionMessages msg = AttachmentUtilities.validate(attachment, services);
351 if (!msg.isEmpty()) {
352 if (log.isDebugEnabled()) {
353 log.debug("validateAttachment: failed to validate, " + msg);
354 }
355 errors.add(msg);
356 }
357 }
358 }
359
360 private static void validateProjectFields(Project project,
361 HttpServletRequest request, ActionErrors errors) {
362 List<CustomField> projectFields = project.getCustomFields();
363 if (null != projectFields && projectFields.size() > 0) {
364 HttpSession session = request.getSession();
365
366 Locale locale = ITrackerResources.getLocale();
367 if (session != null) {
368 locale = (Locale) session.getAttribute(Constants.LOCALE_KEY);
369 }
370
371 ResourceBundle bundle = ITrackerResources.getBundle(locale);
372 Iterator<CustomField> it = projectFields.iterator();
373 while (it.hasNext()) {
374 CustomField customField = it.next();
375 String fieldValue = request.getParameter("customFields("
376 + customField.getId() + ")");
377 if (fieldValue != null && !fieldValue.equals("")) {
378
379
380
381
382
383 try {
384 customField.checkAssignable(fieldValue, locale, bundle);
385 } catch (IssueException ie) {
386 String label = CustomFieldUtilities.getCustomFieldName(
387 customField.getId(), locale);
388 errors.add(ActionMessages.GLOBAL_MESSAGE,
389 new ActionMessage(ie.getType(), label));
390 }
391 } else if (customField.isRequired()) {
392 String label = CustomFieldUtilities.getCustomFieldName(
393 customField.getId(), locale);
394 errors.add(ActionMessages.GLOBAL_MESSAGE,
395 new ActionMessage(IssueException.TYPE_CF_REQ_FIELD,
396 label));
397 }
398 }
399 }
400 }
401
402 private static void validateProjectScripts(Project project, ActionErrors errors, IssueForm form)
403 throws WorkflowException {
404
405 List<ProjectScript> scripts = project.getScripts();
406 WorkflowUtilities.processFieldScripts(scripts,
407 WorkflowUtilities.EVENT_FIELD_ONVALIDATE, null, errors, form);
408 }
409
410 }