View Javadoc

1   package com.atlassian.jira.workflow.transition;
2   
3   import java.sql.Timestamp;
4   import java.util.ArrayList;
5   import java.util.Collections;
6   import java.util.Comparator;
7   import java.util.Iterator;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.TreeMap;
11  
12  import org.ofbiz.core.entity.GenericValue;
13  
14  import com.atlassian.core.ofbiz.CoreFactory;
15  import com.atlassian.jira.issue.Issue;
16  import com.atlassian.jira.ofbiz.DefaultOfBizDelegator;
17  import com.atlassian.jira.ofbiz.OfBizDelegator;
18  import com.atlassian.jira.util.EasyList;
19  import com.atlassian.jira.util.map.EasyMap;
20  import com.atlassian.jira.workflow.transition.step.StepImpl;
21  import com.atlassian.jira.workflow.transition.summary.Transition;
22  import com.atlassian.jira.workflow.transition.summary.TransitionSummary;
23  
24  /**
25   * @FQCN com.atlassian.jira.workflow.transition.DefaultTransitionManager
26   * @description 
27   * TransitionSummary part from JIRA Suite plugin
28   * @author Kaamelot, Gustavo Martin (TransitionSummary part from JIRA Suite plugin)
29   * @since 3.10.1.3x
30   * @version 3.10.1.34
31   */
32  public class DefaultTransitionManager implements TransitionManager {
33  
34  	public static String WF_CURRENT_STEP = "OSCurrentStep";
35  
36  	public static String WF_HISTORY_STEP = "OSHistoryStep";
37  
38  	public List getTransitions(Issue _issue) {
39  		return getTransitions(_issue.getWorkflowId());
40  	}
41  
42  	public List getTransitions(final GenericValue _issue) {
43  		return getTransitions(_issue.getLong("entryId"));
44  	}
45  
46  	public List getTransitions(final Long _entryId) {
47  		List allSteps = new ArrayList();
48  
49  		OfBizDelegator delegator = new DefaultOfBizDelegator(CoreFactory.getGenericDelegator());
50  		Map params = EasyMap.build("entryId", _entryId);
51  		List workflowSteps = delegator.findByAnd(WF_HISTORY_STEP, params, EasyList.build("finishDate ASC"));
52  		workflowSteps.addAll(delegator.findByAnd(WF_CURRENT_STEP, params));
53  
54  		for (Iterator iterator = workflowSteps.iterator(); iterator.hasNext();) {
55  			GenericValue gv = (GenericValue) iterator.next();
56  			allSteps.add(new StepImpl(gv));
57  		}
58  
59  		return allSteps;
60  	}
61  
62  	/**
63  	 * @param gvIssue the current issue.
64  	 * @return a List with the Transition Summaries.
65  	 * 
66  	 * It obtains all Transition Summaries.
67  	 */
68  	public List getTransitionSummary(final Issue issue) {
69  		Map summary = new TreeMap();
70  		Timestamp tsCreated = issue.getTimestamp("created");
71  		List retList = new ArrayList();
72  
73  		// Reads all status changes, associated with the execution of transitions.
74  		List statusChanges = getStatusChanges(issue, tsCreated);
75  
76  		Iterator itStatuses = statusChanges.iterator();
77  		if (!itStatuses.hasNext()) {
78  			retList = Collections.EMPTY_LIST;
79  		}
80  
81  		while (itStatuses.hasNext()) {
82  			Transition trans = (Transition) itStatuses.next();
83  
84  			// Sets an ID for the Transition.
85  			String transitionId = trans.getFromStatus().getId().toString() + "to" + trans.getToStatus().getId().toString();
86  
87  			// System.out.println("transition found: " + transitionId); // Debug output
88  
89  			TransitionSummary tranSummary = null;
90  			if (summary.containsKey(transitionId)) {
91  				tranSummary = (TransitionSummary) summary.get(transitionId);
92  			} else {
93  				tranSummary = new TransitionSummary(transitionId, trans.getFromStatus(), trans.getToStatus());
94  
95  				summary.put(transitionId, tranSummary);
96  				retList.add(tranSummary);
97  			}
98  
99  			// Adds the current Transition to the corresponding TransitionSummary.
100 			tranSummary.addTransition(trans);
101 		}
102 
103 		return retList;
104 	}
105 
106 	/**
107 	 * @param issue the current issue.
108 	 * @param tsCreated when the issue was created. It allows to calculate the duration of the first transition.
109 	 * @return a List with the Status Changes.
110 	 * 
111 	 * It obtains all status changes data from the Change History.
112 	 */
113 	protected List getStatusChanges(final Issue issue, final Timestamp tsCreated) {
114 		List retList = new ArrayList();
115 		Timestamp tsStartDate = new Timestamp(tsCreated.getTime());
116 
117 		OfBizDelegator delegator = new DefaultOfBizDelegator(CoreFactory.getGenericDelegator());
118 		Map params = EasyMap.build("issue", issue.getLong("id"));
119 		List changeGroups = delegator.findByAnd("ChangeGroup", params);
120 
121 		GenericValue changeGroup;
122 		GenericValue changeItem;
123 
124 		// Added by caisd_1998 at hotmail dot com
125 		Collections.sort(changeGroups, new Comparator() {
126 			public int compare(Object o1, Object o2) {
127 				GenericValue c1 = (GenericValue) o1;
128 				GenericValue c2 = (GenericValue) o2;
129 				return c1.getTimestamp("created").compareTo(c2.getTimestamp("created"));
130 			}
131 		});
132 
133 		Iterator itGroups = changeGroups.iterator();
134 		while (itGroups.hasNext()) {
135 
136 			changeGroup = (GenericValue) itGroups.next();
137 
138 			// Obtains all ChangeItems that contains an status change.
139 			Map paramsItem = EasyMap.build("group", changeGroup.getLong("id"), "field", "status");
140 			List changeItems = delegator.findByAnd("ChangeItem", paramsItem);
141 
142 			Iterator itItems = changeItems.iterator();
143 			while (itItems.hasNext()) {
144 				changeItem = (GenericValue) itItems.next();
145 
146 				// And it creates the corresponding Transition.
147 				Transition tran = new Transition();
148 				tran.setChangedBy(changeGroup.getString("author"));
149 				tran.setChangedAt(changeGroup.getTimestamp("created"));
150 				tran.setFromStatus(Long.valueOf(changeItem.getString("oldvalue")));
151 				tran.setToStatus(Long.valueOf(changeItem.getString("newvalue")));
152 				tran.setStartAt(tsStartDate);
153 
154 				retList.add(tran);
155 
156 				// It is used to calculate the duration of the next transition.
157 				tsStartDate = new Timestamp(changeGroup.getTimestamp("created").getTime());
158 			}
159 		}
160 
161 		return retList;
162 	}
163 
164 }