1 package com.atlassian.jira.workflow.function;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.Map;
8
9 import org.apache.log4j.Category;
10
11 import webwork.action.ActionContext;
12
13 import com.atlassian.jira.ComponentManager;
14 import com.atlassian.jira.ManagerFactory;
15 import com.atlassian.jira.issue.CustomFieldManager;
16 import com.atlassian.jira.issue.ModifiedValue;
17 import com.atlassian.jira.issue.MutableIssue;
18 import com.atlassian.jira.issue.customfields.CustomFieldUtils;
19 import com.atlassian.jira.issue.fields.CustomField;
20 import com.atlassian.jira.issue.fields.Field;
21 import com.atlassian.jira.issue.fields.FieldManager;
22 import com.atlassian.jira.issue.fields.screen.FieldScreen;
23 import com.atlassian.jira.issue.fields.screen.FieldScreenImpl;
24 import com.atlassian.jira.issue.fields.screen.FieldScreenManager;
25 import com.atlassian.jira.issue.fields.screen.FieldScreenRenderer;
26 import com.atlassian.jira.issue.fields.screen.FieldScreenRendererFactory;
27 import com.atlassian.jira.issue.fields.screen.FieldScreenScheme;
28 import com.atlassian.jira.issue.fields.screen.issuetype.IssueTypeScreenSchemeManager;
29 import com.atlassian.jira.issue.operation.IssueOperations;
30 import com.atlassian.jira.web.bean.I18nBean;
31 import com.atlassian.jira.workflow.ExtendedWorkflowManager;
32 import com.atlassian.jira.workflow.JiraWorkflowMetaAttributes;
33 import com.atlassian.seraph.auth.DefaultAuthenticator;
34 import com.opensymphony.module.propertyset.PropertySet;
35 import com.opensymphony.user.User;
36 import com.opensymphony.util.TextUtils;
37 import com.opensymphony.workflow.InvalidInputException;
38 import com.opensymphony.workflow.WorkflowException;
39 import com.opensymphony.workflow.loader.ActionDescriptor;
40 import com.opensymphony.workflow.loader.DescriptorFactory;
41 import com.opensymphony.workflow.loader.ValidatorDescriptor;
42 import com.opensymphony.workflow.loader.WorkflowDescriptor;
43
44
45
46
47
48
49
50
51
52 public abstract class ATransitionFunction implements ITransitionFunction {
53
54 protected final static Category log = Category.getInstance(ATransitionFunction.class);
55
56 protected FieldManager fieldManager = ManagerFactory.getFieldManager();
57
58 protected CustomFieldManager customFieldManager = ManagerFactory.getCustomFieldManager();
59
60 protected static FieldScreenRendererFactory fieldScreenRendererFactory = (FieldScreenRendererFactory) ComponentManager.getComponentInstanceOfType(FieldScreenRendererFactory.class);
61
62 protected ActionDescriptor actionDescriptor;
63
64 protected FieldScreenRenderer fieldScreenRenderer;
65
66 protected IssueTypeScreenSchemeManager issueTypeScreenSchemeManager = null;
67
68 protected InvalidInputException invalidInputException = null;
69
70 private FieldScreen screen = null;
71
72 private MutableIssue issue = null;
73
74 private I18nBean i18nBean;
75
76 private Map fieldErrors = new HashMap();
77
78 public void init(Map transientVars, Map args, PropertySet ps) throws InvalidInputException, WorkflowException {
79 issue = getIssue(transientVars);
80 actionDescriptor = getActionDescriptor(transientVars);
81 }
82
83 public ActionDescriptor getActionDescriptor(final Map transientVars) {
84
85 Integer actionId = (Integer) transientVars.get("actionId");
86 WorkflowDescriptor workflowDescriptor = (WorkflowDescriptor) transientVars.get("descriptor");
87 ActionDescriptor actionDescriptor = workflowDescriptor.getAction(actionId.intValue());
88 return actionDescriptor;
89 }
90
91
92
93 public FieldScreen getScreen() {
94 if (screen == null) {
95 screen = getFieldScreen(actionDescriptor);
96 }
97 return screen;
98 }
99
100
101
102
103
104
105 public FieldScreen getFieldScreen(ActionDescriptor actionDescriptor) {
106 FieldScreenManager fieldScreenManager = ComponentManager.getInstance().getFieldScreenManager();
107 FieldScreen fieldScreen = null;
108 try {
109 Long operationId = ExtendedWorkflowManager.getOperationId(actionDescriptor);
110 if (operationId !=null) {
111 FieldScreenScheme fieldScreenScheme = getIssueTypeScreenSchemeManager().getFieldScreenScheme(getIssue());
112 fieldScreen = fieldScreenScheme.getFieldScreen(IssueOperations.getIssueOperation(operationId));
113 } else {
114 if (TextUtils.stringSet(actionDescriptor.getView())) {
115 Map metaAttributes = actionDescriptor.getMetaAttributes();
116 String str = metaAttributes.get(JiraWorkflowMetaAttributes.JIRA_META_ATTRIBUTE_SCREEN_ID).toString();
117 Long screenId = new Long(str);
118
119 fieldScreen = fieldScreenManager.getFieldScreen(screenId);
120 }
121 }
122 } catch (Exception e) {
123 fieldScreen = new FieldScreenImpl(fieldScreenManager);
124 }
125
126 return fieldScreen;
127 }
128
129
130
131
132
133
134 public FieldScreenRenderer getFieldScreenRenderer() {
135 if (fieldScreenRenderer == null) {
136 Long operationId = ExtendedWorkflowManager.getOperationId(actionDescriptor);
137 if (operationId !=null) {
138 fieldScreenRenderer = ComponentManager.getInstance().getFieldScreenRendererFactory().getFieldScreenRenderer(getRemoteUser(), getIssue(), IssueOperations.getIssueOperation(operationId), false);
139 } else {
140 fieldScreenRenderer = fieldScreenRendererFactory.getFieldScreenRenderer(getRemoteUser(), getIssue(), actionDescriptor);
141 }
142 }
143 return fieldScreenRenderer;
144 }
145
146
147 public MutableIssue getIssue() {
148 return issue;
149 }
150
151 protected void setIssue(final MutableIssue _issue) {
152 issue = _issue;
153 }
154
155 public MutableIssue getIssue(final Map transientVars) {
156 MutableIssue issue = (MutableIssue) transientVars.get("issue");
157 return issue;
158 }
159
160 public I18nBean getI18nBean() {
161 if (i18nBean == null) {
162 i18nBean = new I18nBean();
163 i18nBean.getI18nLocations().addAll(getI18nLocations());
164 }
165 return i18nBean;
166 }
167
168 public Collection getI18nLocations() {
169 Collection i18nLocations = new ArrayList();
170 Class thisClass = getClass();
171 Class[] itsInterfaces = thisClass.getInterfaces();
172
173 for (int i = 0; i < itsInterfaces.length; i++) {
174 Class oneInterface = itsInterfaces[i];
175 Class itsSuperClass = oneInterface.getSuperclass();
176 if (itsSuperClass != null && itsSuperClass.getName().equals("I18nProvider")) {
177
178 i18nLocations.add(oneInterface.getName());
179 }
180 }
181 i18nLocations.add(ATransitionFunction.class.getName());
182 return i18nLocations;
183 }
184
185 protected Object getValueOfModifiedCustomField(String _customFieldName) {
186 Object value = null;
187 CustomField customfield = customFieldManager.getCustomFieldObjectByName(_customFieldName);
188 if (customfield != null) {
189 value = getValueOfModifiedField(customfield.getId());
190 }
191 return value;
192 }
193
194 protected Object getValueOfModifiedField(Field _field) {
195 return getValueOfModifiedField(_field.getId());
196 }
197
198 protected Object getValueOfModifiedField(String _fieldId) {
199 Object valueOfModifiedField = null;
200 Map modifiedFields;
201 modifiedFields = getIssue().getModifiedFields();
202 if (!modifiedFields.isEmpty()) {
203 ModifiedValue mv = (ModifiedValue) modifiedFields.get(_fieldId);
204 if (mv != null) {
205 valueOfModifiedField = mv.getNewValue();
206 }
207 }
208 return valueOfModifiedField;
209 }
210
211 public void throwOnError() throws InvalidInputException {
212
213 if (invalidInputException != null) {
214
215 for (Iterator it = invalidInputException.getErrors().keySet().iterator(); it.hasNext();) {
216 String fieldId = (String) it.next();
217 String fieldKey = CustomFieldUtils.getCustomFieldKey(fieldId);
218 if (getScreen() == null || !getScreen().containsField(fieldKey)) {
219 String error = (String) invalidInputException.getErrors().get(fieldId);
220 invalidInputException.addError(error);
221 }
222 }
223
224 throw invalidInputException;
225 }
226 }
227
228 protected void setErrorOnCustomField(String _customfieldName, String errmsg) {
229 Field field = customFieldManager.getCustomFieldObjectByName(_customfieldName);
230 setError(field, errmsg);
231 }
232
233 protected void setError(String fieldId, String errmsg) {
234 Field field = fieldManager.getField(fieldId);
235 setError(field, errmsg);
236 }
237
238 protected void setError(Field field, String errmsg) {
239 getI18nBean();
240 if (invalidInputException == null) {
241 invalidInputException = new InvalidInputException("");
242 }
243 if (errmsg == null) {
244 errmsg = "validator.message.field.required";
245 }
246 if (field == null) {
247 invalidInputException.addError(i18nBean.getText(errmsg));
248 } else {
249 invalidInputException.addError(field.getId(), i18nBean.getText(errmsg, field.getName()));
250 }
251 }
252
253 public void addErrors(Map _errors) {
254 if (invalidInputException == null) {
255 invalidInputException = new InvalidInputException();
256 }
257 invalidInputException.getErrors().putAll(_errors);
258 }
259
260 public void addErrors(InvalidInputException _invalidInputException) {
261 if (_invalidInputException != null) {
262 addErrors(_invalidInputException.getErrors());
263 }
264 }
265
266 public InvalidInputException getInvalidInputException() {
267 return invalidInputException;
268 }
269
270 public void setInvalidInputException(InvalidInputException invalidInputException) {
271 this.invalidInputException = invalidInputException;
272 }
273
274 public User getRemoteUser() {
275 return (User) ActionContext.getSession().get(DefaultAuthenticator.LOGGED_IN_KEY);
276 }
277
278 public static ValidatorDescriptor makeDescriptor(String permission, String _validatorFQCN) {
279 DescriptorFactory factory = DescriptorFactory.getFactory();
280 ValidatorDescriptor permValidator = factory.createValidatorDescriptor();
281 permValidator.setType("class");
282 permValidator.getArgs().put("class.name", _validatorFQCN);
283 return permValidator;
284 }
285
286 public Map getFieldErrors() {
287 return fieldErrors;
288 }
289
290 public void setFieldErrors(Map fieldErrors) {
291 this.fieldErrors = fieldErrors;
292 }
293
294 public IssueTypeScreenSchemeManager getIssueTypeScreenSchemeManager() {
295 if (issueTypeScreenSchemeManager == null) {
296 issueTypeScreenSchemeManager = (IssueTypeScreenSchemeManager)ComponentManager.getComponentInstanceOfType(IssueTypeScreenSchemeManager.class);
297 }
298 return issueTypeScreenSchemeManager;
299 }
300
301 }