View Javadoc

1   package com.atlassian.jira.web.action.issue;
2   
3   import java.util.HashMap;
4   import java.util.Iterator;
5   import java.util.Map;
6   
7   import org.apache.commons.lang.exception.ExceptionUtils;
8   import org.ofbiz.core.entity.GenericValue;
9   
10  import webwork.dispatcher.ActionResult;
11  
12  import com.atlassian.core.action.ActionUtils;
13  import com.atlassian.core.ofbiz.CoreFactory;
14  import com.atlassian.jira.ComponentManager;
15  import com.atlassian.jira.action.ActionNames;
16  import com.atlassian.jira.bc.issue.comment.CommentService;
17  import com.atlassian.jira.config.ConstantsManager;
18  import com.atlassian.jira.config.SubTaskManager;
19  import com.atlassian.jira.exception.CreateException;
20  import com.atlassian.jira.issue.IssueFactory;
21  import com.atlassian.jira.issue.IssueFieldConstants;
22  import com.atlassian.jira.issue.fields.OrderableField;
23  import com.atlassian.jira.issue.fields.layout.field.FieldLayoutItem;
24  import com.atlassian.jira.issue.fields.layout.field.FieldLayoutManager;
25  import com.atlassian.jira.issue.fields.screen.FieldScreenRenderLayoutItem;
26  import com.atlassian.jira.issue.fields.screen.FieldScreenRenderTab;
27  import com.atlassian.jira.issue.fields.screen.FieldScreenRendererFactory;
28  import com.atlassian.jira.issue.link.IssueLinkManager;
29  import com.atlassian.jira.issue.managers.ExtendedIssueManager;
30  import com.atlassian.jira.util.map.EasyMap;
31  import com.atlassian.jira.workflow.WorkflowFunctionUtils;
32  import com.atlassian.jira.workflow.WorkflowManager;
33  import com.atlassian.jira.workflow.condition.ValidatingIssueCondition;
34  import com.opensymphony.workflow.InvalidInputException;
35  
36  /**
37   * FQCN : com.atlassian.jira.web.action.issue.ExtendedEditIssue
38   * @author Kaamelot
39   * @since 3.10.1.30
40   * Description : Extends EditIssue in order to perform an Issue Validation on Edit Action with validator specified in Workflow.
41   *
42   */
43  public class ExtendedEditIssue extends EditIssue {
44  
45  	protected IssueFactory issueFactory;
46  
47  	public ExtendedEditIssue(IssueLinkManager _issueLinkManager, SubTaskManager _subTaskManager, ConstantsManager _constantsManager, FieldLayoutManager _fieldLayoutManager,
48  				WorkflowManager _workflowManager, FieldScreenRendererFactory _fieldScreenRendererFactory, CommentService _commentService, IssueFactory _issueFactory) {
49  		super(_issueLinkManager, _subTaskManager, _constantsManager, _fieldLayoutManager, _workflowManager, _fieldScreenRendererFactory, _commentService);
50  		issueFactory = _issueFactory;
51  	}
52  
53  	/**	 */
54  	private static final long serialVersionUID = 1L;
55  
56  	/**
57  	 * Update Issue From FieldValuesHolder
58  	 * @throws Exception
59  	 */
60  	protected void updateIssueFromFieldValuesHolder() throws Exception {
61  		for (Iterator iterator = getFieldScreenRenderer().getFieldScreenRenderTabs().iterator(); iterator.hasNext();) {
62  			FieldScreenRenderTab fieldScreenRenderTab = (FieldScreenRenderTab) iterator.next();
63  			for (Iterator iterator1 = fieldScreenRenderTab.getFieldScreenRenderLayoutItemsForProcessing().iterator(); iterator1.hasNext();) {
64  				FieldScreenRenderLayoutItem fieldScreenRenderLayoutItem = (FieldScreenRenderLayoutItem) iterator1.next();
65  				if (fieldScreenRenderLayoutItem.isShow(getIssueObject())) {
66  					fieldScreenRenderLayoutItem.getOrderableField().updateIssue(fieldScreenRenderLayoutItem.getFieldLayoutItem(), getIssueObject(), getCustomFieldValuesHolder());
67  				}
68  			}
69  		}
70  		// This hack is here until the comment field becomes placeable on screens by the users
71  		OrderableField commentField = (OrderableField) ComponentManager.getInstance().getFieldManager().getField(IssueFieldConstants.COMMENT);
72  		FieldLayoutItem fieldLayoutItem = ComponentManager.getInstance().getFieldLayoutManager().getFieldLayout(getIssueObject().getProject(), getIssueObject().getIssueTypeObject().getId())
73  					.getFieldLayoutItem(commentField);
74  		commentField.updateIssue(fieldLayoutItem, getIssueObject(), getCustomFieldValuesHolder());
75  
76  	}
77  
78  	/**
79  	 *  Extend doExecute() in order to :
80  	 *  - launch Issue Validation
81  	 *  - extract possible InvalidInputException
82  	 */
83  	protected String doExecute() throws Exception {
84  		try {
85  			updateIssueFromFieldValuesHolder();
86  
87  			validateIssue();
88  
89  			Map actionParams = EasyMap.build("issue", getIssueObject().getGenericValue(), "issueObject", getIssueObject(), "remoteUser", getRemoteUser());
90  
91  			ActionResult aResult = CoreFactory.getActionDispatcher().execute(ActionNames.ISSUE_UPDATE, actionParams);
92  
93  			ActionUtils.checkForErrors(aResult);
94  
95  			return getRedirect(getViewUrl());
96  		} catch (Throwable e) {
97  			analyseException(e);
98  			return ERROR;
99  		}
100 	}
101 
102 	/** Analyse Exception in order to raise Errors to GUI
103 	 * @param e
104 	 */
105 	protected void analyseException(Throwable e) {
106 		if (extractInvalidInputException(e)) {
107 			addErrorMessage(getText("admin.errors.issues.exception.occured", "..."));
108 		} else if (e instanceof CreateException) {
109 			log.error(e, e);
110 			String errMsg = getText("admin.errors.issues.exception.occured", e.getMessage());
111 			addErrorMessage(errMsg);
112 		} else {
113 			log.error("Exception occurred editing issue: " + e, e);
114 			addErrorMessage((e.getMessage() != null ? e.getMessage() : ExceptionUtils.getFullStackTrace(e)));
115 		}
116 	}
117 
118 	/**
119 	 * Validate Issue. Validation is delegated to ExtendedIssueManager
120 	 * @throws Exception
121 	 */
122 	protected void validateIssue() throws Exception {
123 		if (getIssueManager() instanceof ExtendedIssueManager) {
124 			ExtendedIssueManager extendedIssueManager = (ExtendedIssueManager) getIssueManager();
125 			HashMap fields = new HashMap();
126 			fields.put("issue", getIssueObject());
127 			GenericValue originalIssueGV = getIssueObject().getGenericValue();
128 			fields.put(WorkflowFunctionUtils.ORIGNAL_ISSUE_KEY, issueFactory.getIssue(originalIssueGV));
129 			fields.put("pkey", getProject().getString("key")); // Allow ${pkey} in args
130 			fields.put(ValidatingIssueCondition.VALIDATING_ISSUE_KEY, Boolean.TRUE); // Force to true in order to passe the Condition
131 			// fields.put("submitbutton", getAuxiliarySubmitButtonValue()); // let the workflow know which submit button was pressed
132 			extendedIssueManager.validateIssue(getRemoteUser(), fields);
133 		} else {
134 			log.error("No Extended Validation performed on Issue because no ExtendedIssueManager is available.");
135 		}
136 	}
137 
138 	/** Extract InvalidInputException and push Error by Field Id.
139 	 * @param t Throwable to analyse 
140 	 */
141 	protected boolean extractInvalidInputException(Throwable t) {
142 		boolean hasInvalidInputException = false;
143 		if (t instanceof InvalidInputException) {
144 			hasInvalidInputException = true;
145 			InvalidInputException iie = (InvalidInputException) t;
146 			for (Iterator iterator = iie.getErrors().entrySet().iterator(); iterator.hasNext();) {
147 				Map.Entry entry = (Map.Entry) iterator.next();
148 				addError((String) entry.getKey(), (String) entry.getValue());
149 			}
150 		}
151 		if (t.getCause() != null) {
152 			hasInvalidInputException = hasInvalidInputException || extractInvalidInputException(t.getCause());
153 		}
154 		return hasInvalidInputException;
155 	}
156 
157 }