View Javadoc

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   * FQCN : com.atlassian.jira.workflow.function.ATransitionFunction
46   * @author Kaamelot
47   * @since
48   * @history - 28 nov. 06 - Class Creation
49   * Description :
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  	/** @return FieldScreen as it is defined in the FieldScreenScheme for this Workflow Action   
92  	 */
93  	public FieldScreen getScreen() {
94  		if (screen == null) {
95  			screen = getFieldScreen(actionDescriptor);
96  		}
97  		return screen;
98  	}
99  
100 	/**
101 	 * @see com.atlassian.plugin.util.WorkflowUtils#getFieldScreen(ActionDescriptor)
102 	 * @param actionDescriptor
103 	 * @return
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 	 * Instead of getScreen(), getFieldScreenRenderer() returns the screen only with visible fields (depending on the RemoteUser) 
132 	 * @return
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 		// Is one of its Interface a I18n Bundle Key Provider
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 				// Yes, we try to find the translation
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 }