import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.StatusCategoryManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.DocumentIssueImpl
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.issue.search.providers.LuceneSearchProvider
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.rest.api.util.ErrorCollection
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.query.Query
import com.decadis.jira.xchart.api.GroupValueExtractor
import com.decadis.jira.xchart.api.ValueExtractor
import com.decadis.jira.xchart.calculating.ValueExtractorBuilder
import com.decadis.jira.xchart.grouping.GroupValueExtractorFactory
import org.apache.commons.lang.StringUtils
import org.apache.lucene.document.Document
import java.lang.reflect.Field
/**
* Get issues on JQL
*
* @param jqlString
*
* @return
*/
static List<Issue> getIssues(final String jqlString) {
final LuceneSearchProvider luceneSearchProvider = ComponentAccessor.getComponent(LuceneSearchProvider.class)
final JqlQueryParser jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser.class)
Query query = jqlQueryParser.parseQuery(jqlString)
SearchResults searchResults = luceneSearchProvider.searchOverrideSecurity(query, null, PagerFilter.getUnlimitedFilter(), null)
return searchResults.getIssues()
}
/**
*
* @param issue
* @param groupValueExtractor
*
* @return
*/
static Map<String, String> getGroups(final Issue issue, final GroupValueExtractor<?> groupValueExtractor) {
final Map<String, String> result = new TreeMap<>()
try{
Field documentField = DocumentIssueImpl.class.getDeclaredField("document")
documentField.setAccessible(true)
Document document = (Document) documentField.get(issue)
for (String value : groupValueExtractor.getGroups(document)) {
if (StringUtils.isNotBlank(value)) {
result.put(value, groupValueExtractor.getResolvedValue(value, issue))
}
}
}
catch (Exception e){
}
return result
}
/**
* fill all empty values with empty map
*
* @param data
* @param groups
*
* @return
*/
static void fillMissingValues(final Map<String, Map<String, Map<String, Integer>>> data, final Map<String, String> groups)
{
for (Map.Entry<String, Map<String, Map<String, Integer>>> epics : data.entrySet()){
Map<String, Map<String, Integer>> group = epics.getValue()
for(String key : groups.keySet())
{
if(!group.containsKey(key)){
group.put(key, new TreeMap<>())
}
}
}
}
final StatusCategoryManager statusCategoryManager = ComponentAccessor.getComponent(StatusCategoryManager.class)
// create group value extractor
final GroupValueExtractor<?> groupValueExtractor = GroupValueExtractorFactory.Create(GroupBy, "");
Map<String, Object> result = new HashMap<>()
Map<String, String> groups = new TreeMap<>()
Map<String, String> epicData = new TreeMap<>()
Map<String, Integer> statusMap = new TreeMap<>()
Map<String, String> statusCategoriesMeta = new HashMap<>()
Map<String, Map<String, Map<String, Integer>>> data = new HashMap<>()
// get all epic issues
List<Issue> epics = getIssues(JQL);
// mapping status category values
statusCategoryManager.getStatusCategories().each {
if (!"undefined".equalsIgnoreCase(it.getKey())){
statusMap.put(it.getKey(), 0)
statusCategoriesMeta.put(it.getKey(), it.getTranslatedName())
}
}
for (Issue epic : epics)
{
Map<String, Map<String, Integer>> groupData = new TreeMap<>()
for (Issue story : getIssues("cf["+ Epic_Link_FieldID +"] = " + epic.getKey()))
{
Map<String, String> groupsTemp = getGroups(story, groupValueExtractor)
groups.putAll(groupsTemp)
for(String groupName : groupsTemp.keySet())
{
Map<String, Integer> statusMapTemp = groupData.get(groupName)
if(statusMapTemp == null)
{
statusMapTemp = new TreeMap<>(statusMap)
}
String statusCategoryKey = story.getStatus().getStatusCategory().getKey()
if(statusCategoryKey != null)
{
statusMapTemp.put(statusCategoryKey, ++statusMapTemp.get(statusCategoryKey))
}
groupData.put(groupName, statusMapTemp)
}
}
data.put(epic.getKey(), groupData)
epicData.put(epic.getKey(), epic.getSummary())
}
fillMissingValues(data, groups)
result.put("groups", groups)
result.put("data", data)
result.put("statusCategories", statusCategoriesMeta)
result.put("epicData", epicData)
result.put("contextPath", ComponentAccessor.getApplicationProperties().getString("jira.baseurl"))
return result |
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.config.StatusCategoryManager
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.DocumentIssueImpl
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.link.IssueLink
import com.atlassian.jira.issue.search.SearchResults
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.rest.api.util.ErrorCollection
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.query.Query
import com.decadis.jira.xchart.api.GroupValueExtractor
import com.decadis.jira.xchart.api.ValueExtractor
import com.decadis.jira.xchart.calculating.ValueExtractorBuilder
import com.decadis.jira.xchart.grouping.GroupValueExtractorFactory
import org.apache.commons.lang.StringUtils
import org.apache.lucene.document.Document
import com.atlassian.jira.bc.issue.search.SearchService;
import java.lang.reflect.Field
/**
* Get issues on JQL
*
* @param jqlString
*
* @return
*/
List<Issue> getIssues(final String jqlString) {
SearchService serchService = ComponentAccessor.getComponentOfType(SearchService.class);
SearchService.ParseResult parseResult =
serchService.parseQuery(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(),
jqlString);
if (!parseResult.isValid())
{
throw new Exception("jql is not valid. jql was "+jqlString);
}
Query query = parseResult.getQuery();
SearchResults sr =
serchService.search(ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser(),
query, PagerFilter.getUnlimitedFilter());
return sr.getResults();
}
/**
*
* @param issue
* @param groupValueExtractor
*
* @return
*/
static Map<String, String> getGroups(final Issue issue, final GroupValueExtractor<?> groupValueExtractor) {
final Map<String, String> result = new TreeMap<>()
try{
Field documentField = DocumentIssueImpl.class.getDeclaredField("document")
documentField.setAccessible(true)
Document document = (Document) documentField.get(issue)
for (String value : groupValueExtractor.getGroups(document)) {
if (StringUtils.isNotBlank(value)) {
result.put(value, groupValueExtractor.getResolvedValue(value, issue))
}
}
}
catch (Exception e){
}
return result
}
/**
* fill all empty values with empty map
*
* @param data
* @param groups
*
* @return
*/
static void fillMissingValues(final Map<String, Map<String, Map<String, Integer>>> data, final Map<String, String> groups)
{
for (Map.Entry<String, Map<String, Map<String, Integer>>> epics : data.entrySet()){
Map<String, Map<String, Integer>> group = epics.getValue()
for(String key : groups.keySet())
{
if(!group.containsKey(key)){
group.put(key, new TreeMap<>())
}
}
}
}
final StatusCategoryManager statusCategoryManager = ComponentAccessor.getComponent(StatusCategoryManager.class)
// create group value extractor
final GroupValueExtractor<?> groupValueExtractor = GroupValueExtractorFactory.Create(GroupBy, "");
Map<String, Object> result = new HashMap<>()
Map<String, String> groups = new TreeMap<>()
Map<String, String> epicData = new TreeMap<>()
Map<String, Integer> statusMap = new TreeMap<>()
Map<String, String> statusCategoriesMeta = new HashMap<>()
Map<String, Map<String, Map<String, Integer>>> data = new HashMap<>()
// get all epic issues
List<Issue> epics = getIssues(JQL);
// mapping status category values
statusCategoryManager.getStatusCategories().each {
if (!"undefined".equalsIgnoreCase(it.getKey())){
statusMap.put(it.getKey(), 0)
statusCategoriesMeta.put(it.getKey(), it.getTranslatedName())
}
}
for (Issue epic : epics)
{
Map<String, Map<String, Integer>> groupData = new TreeMap<>()
for (Issue story : getIssues("cf["+ Epic_Link_FieldID +"] = " + epic.getKey()))
{
Map<String, String> groupsTemp = getGroups(story, groupValueExtractor)
groups.putAll(groupsTemp)
for(String groupName : groupsTemp.keySet())
{
Map<String, Integer> statusMapTemp = groupData.get(groupName)
if(statusMapTemp == null)
{
statusMapTemp = new TreeMap<>(statusMap)
}
String statusCategoryKey = story.getStatus().getStatusCategory().getKey()
if(statusCategoryKey != null)
{
statusMapTemp.put(statusCategoryKey, ++statusMapTemp.get(statusCategoryKey))
}
groupData.put(groupName, statusMapTemp)
}
}
data.put(epic.getKey(), groupData)
epicData.put(epic.getKey(), epic.getSummary())
}
fillMissingValues(data, groups)
result.put("groups", groups)
result.put("data", data)
result.put("statusCategories", statusCategoriesMeta)
result.put("epicData", epicData)
result.put("contextPath", ComponentAccessor.getApplicationProperties().getString("jira.baseurl"))
return result |
|