From 8d204f5b1169e4a984eaea21ac35e169d7ef295e Mon Sep 17 00:00:00 2001 From: "P. Siegmann" Date: Fri, 21 Aug 2015 15:35:26 +0200 Subject: [PATCH 1/3] small cleanups --- src/main/java/net/rcarz/jiraclient/Issue.java | 65 +++++++------------ 1 file changed, 24 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/rcarz/jiraclient/Issue.java b/src/main/java/net/rcarz/jiraclient/Issue.java index d049a9b..37787b5 100644 --- a/src/main/java/net/rcarz/jiraclient/Issue.java +++ b/src/main/java/net/rcarz/jiraclient/Issue.java @@ -309,11 +309,8 @@ public class Issue extends Resource { final String j = jql; JSON result = null; try { - Map queryParams = new HashMap() { - { - put("jql", j); - } - }; + Map queryParams = new HashMap(); + queryParams.put("jql", j); queryParams.put("maxResults", "1"); URI searchUri = restclient.buildURI(getBaseUri() + "search", queryParams); result = restclient.get(searchUri); @@ -689,13 +686,13 @@ public class Issue extends Resource { JSON result = null; try { + Map params = new HashMap(); + params.put("expand", "projects.issuetypes.fields"); + params.put("projectKeys", pval); + params.put("issuetypeNames", itval); URI createuri = restclient.buildURI( getBaseUri() + "issue/createmeta", - new HashMap() {{ - put("expand", "projects.issuetypes.fields"); - put("projectKeys", pval); - put("issuetypeNames", itval); - }}); + params); result = restclient.get(createuri); } catch (Exception ex) { throw new JiraException("Failed to retrieve issue metadata", ex); @@ -747,11 +744,10 @@ public class Issue extends Resource { JSON result = null; try { + Map params = new HashMap(); + params.put("expand", "transitions.fields"); URI transuri = restclient.buildURI( - getRestUri(key) + "/transitions", - new HashMap() {{ - put("expand", "transitions.fields"); - }}); + getRestUri(key) + "/transitions",params); result = restclient.get(transuri); } catch (Exception ex) { throw new JiraException("Failed to retrieve transitions", ex); @@ -1048,11 +1044,8 @@ public class Issue extends Resource { public static Issue get(RestClient restclient, String key, final String includedFields) throws JiraException { - Map queryParams = new HashMap() { - { - put("fields", includedFields); - } - }; + Map queryParams = new HashMap(); + queryParams.put("fields", includedFields); return new Issue(restclient, realGet(restclient, key, queryParams)); } @@ -1082,14 +1075,11 @@ public class Issue extends Resource { public static Issue get(RestClient restclient, String key, final String includedFields, final String expand) throws JiraException { - Map queryParams = new HashMap() { - { - put("fields", includedFields); - if (expand != null) { - put("expand", expand); - } - } - }; + Map queryParams = new HashMap(); + queryParams.put("fields", includedFields); + if (expand != null) { + queryParams.put("expand", expand); + } return new Issue(restclient, realGet(restclient, key, queryParams)); } @@ -1177,11 +1167,8 @@ public class Issue extends Resource { JSON result = null; try { - Map queryParams = new HashMap() { - { - put("jql", j); - } - }; + Map queryParams = new HashMap(); + queryParams.put("jql", j); if(maxResults != null){ queryParams.put("maxResults", String.valueOf(maxResults)); } @@ -1245,11 +1232,8 @@ public class Issue extends Resource { */ public void refresh(final String includedFields) throws JiraException { - Map queryParams = new HashMap() { - { - put("fields", includedFields); - } - }; + Map queryParams = new HashMap(); + queryParams.put("fields", includedFields); JSONObject result = realGet(restclient, key, queryParams); deserialise(result); } @@ -1346,11 +1330,10 @@ public class Issue extends Resource { try { final String u = username; + Map connectionParams = new HashMap(); + connectionParams.put("username", u); URI uri = restclient.buildURI( - getRestUri(key) + "/watchers", - new HashMap() {{ - put("username", u); - }}); + getRestUri(key) + "/watchers", connectionParams); restclient.delete(uri); } catch (Exception ex) { throw new JiraException( From 9ec500d14666bcb4b641cb93894eb221dc981429 Mon Sep 17 00:00:00 2001 From: "P. Siegmann" Date: Fri, 21 Aug 2015 20:42:33 +0200 Subject: [PATCH 2/3] add iterator() to SearchResult for ease-of-use --- src/main/java/net/rcarz/jiraclient/Issue.java | 158 ++++++++++++++++-- 1 file changed, 146 insertions(+), 12 deletions(-) diff --git a/src/main/java/net/rcarz/jiraclient/Issue.java b/src/main/java/net/rcarz/jiraclient/Issue.java index 37787b5..193969a 100644 --- a/src/main/java/net/rcarz/jiraclient/Issue.java +++ b/src/main/java/net/rcarz/jiraclient/Issue.java @@ -526,6 +526,105 @@ public class Issue extends Resource { } } + + /** + * Iterates over all issues in the query by getting the next page of + * issues when the iterator reaches the last of the current page. + */ + private static class IssueIterator implements Iterator { + private Iterator currentPage; + private RestClient restClient; + private Issue nextIssue; + private Integer maxResults = -1; + private String jql; + private String includedFields; + private String expandFields; + private Integer startAt; + private List issues; + private int total; + + public IssueIterator(RestClient restClient, String jql, + String includedFields, String expandFields, Integer maxResults, Integer startAt) + throws JiraException { + this.restClient = restClient; + this.jql = jql; + this.includedFields = includedFields; + this.expandFields = expandFields; + this.maxResults = maxResults; + this.startAt = startAt; + } + + @Override + public boolean hasNext() { + if (nextIssue != null) { + return true; + } + try { + nextIssue = getNextIssue(); + } catch (JiraException e) { + throw new RuntimeException(e); + } + return nextIssue != null; + } + + @Override + public Issue next() { + if (! hasNext()) { + throw new NoSuchElementException(); + } + Issue result = nextIssue; + nextIssue = null; + return result; + } + + + @Override + public void remove() { + throw new UnsupportedOperationException("Method remove() not support for class " + this.getClass().getName()); + } + + private Issue getNextIssue() throws JiraException { + // first call + if (currentPage == null) { + currentPage = getNextIssues().iterator(); + if (currentPage == null) { + return null; + } else { + return currentPage.next(); + } + } + + if (! currentPage.hasNext()) { + currentPage = getNextIssues().iterator(); + } + + if (currentPage.hasNext()) { + return currentPage.next(); + } else { + return null; + } + } + + private List getNextIssues() throws JiraException { + if (issues == null) { + startAt = Integer.valueOf(0); + } else { + startAt = startAt + issues.size(); + } + + JSON searchResult = executeSearch(restClient, jql, includedFields, expandFields, maxResults, startAt); + + Map map = (Map) searchResult; + + this.startAt = Field.getInteger(map.get("startAt")); + this.maxResults = Field.getInteger(map.get("maxResults")); + this.total = Field.getInteger(map.get("total")); + this.issues = Field.getResourceArray(Issue.class, map.get("issues"), restClient); + return issues; + } + + } + /** * Issue search results structure. */ @@ -534,6 +633,42 @@ public class Issue extends Resource { public int max = 0; public int total = 0; public List issues = null; + private RestClient restClient; + private String jql; + private String includedFields; + private String expandFields; + private Integer maxResults; + private Integer startAt; + private IssueIterator issueIterator; + + public SearchResult(RestClient restClient, String jql, + String includedFields, String expandFields, Integer maxResults, Integer startAt) throws JiraException { + this.restClient = restClient; + this.jql = jql; + this.includedFields = includedFields; + this.expandFields = expandFields; + this.maxResults = maxResults; + this.startAt = startAt; + initSearchResult(); + } + + private void initSearchResult() throws JiraException { + this.issueIterator = new IssueIterator(restClient, jql, includedFields, expandFields, maxResults, startAt); + this.issueIterator.hasNext(); + this.max = issueIterator.maxResults; + this.start = issueIterator.startAt; + this.issues = issueIterator.issues; + this.total = issueIterator.total; + } + + /** + * All issues found. + * + * @return All issues found. + */ + public IssueIterator iterator() { + return issueIterator; + } } public static final class NewAttachment { @@ -1163,7 +1298,15 @@ public class Issue extends Resource { String includedFields, String expandFields, Integer maxResults, Integer startAt) throws JiraException { - final String j = jql; + SearchResult sr = new SearchResult(restclient, jql, includedFields, expandFields, maxResults, startAt); + + return sr; + } + + private static JSON executeSearch(RestClient restclient, String jql, + String includedFields, String expandFields, Integer maxResults, + Integer startAt) throws JiraException { + final String j = jql; JSON result = null; try { @@ -1191,17 +1334,8 @@ public class Issue extends Resource { if (!(result instanceof JSONObject)) { throw new JiraException("JSON payload is malformed"); } - - SearchResult sr = new SearchResult(); - Map map = (Map) result; - - sr.start = Field.getInteger(map.get("startAt")); - sr.max = Field.getInteger(map.get("maxResults")); - sr.total = Field.getInteger(map.get("total")); - sr.issues = Field.getResourceArray(Issue.class, map.get("issues"), restclient); - - return sr; - } + return result; + } /** * Reloads issue data from the JIRA server (issue includes all navigable From 401ca6410b52dc1c237fccfcce2a5e7a4443dfa1 Mon Sep 17 00:00:00 2001 From: "P. Siegmann" Date: Sat, 22 Aug 2015 10:23:35 +0200 Subject: [PATCH 3/3] docs and small cleanups --- src/main/java/net/rcarz/jiraclient/Issue.java | 111 +++++++++++++----- 1 file changed, 79 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/rcarz/jiraclient/Issue.java b/src/main/java/net/rcarz/jiraclient/Issue.java index 193969a..03b8b58 100644 --- a/src/main/java/net/rcarz/jiraclient/Issue.java +++ b/src/main/java/net/rcarz/jiraclient/Issue.java @@ -22,6 +22,7 @@ package net.rcarz.jiraclient; import java.io.File; import java.io.InputStream; import java.net.URI; +import java.net.URISyntaxException; import java.util.*; import net.sf.json.JSON; @@ -533,7 +534,7 @@ public class Issue extends Resource { */ private static class IssueIterator implements Iterator { private Iterator currentPage; - private RestClient restClient; + private RestClient restclient; private Issue nextIssue; private Integer maxResults = -1; private String jql; @@ -543,10 +544,10 @@ public class Issue extends Resource { private List issues; private int total; - public IssueIterator(RestClient restClient, String jql, + public IssueIterator(RestClient restclient, String jql, String includedFields, String expandFields, Integer maxResults, Integer startAt) throws JiraException { - this.restClient = restClient; + this.restclient = restclient; this.jql = jql; this.includedFields = includedFields; this.expandFields = expandFields; @@ -583,6 +584,13 @@ public class Issue extends Resource { throw new UnsupportedOperationException("Method remove() not support for class " + this.getClass().getName()); } + /** + * Gets the next issue, returning null if none more available + * Will ask the next set of issues from the server if the end of the current list of issues is reached. + * + * @return the next issue, null if none more available + * @throws JiraException + */ private Issue getNextIssue() throws JiraException { // first call if (currentPage == null) { @@ -594,10 +602,12 @@ public class Issue extends Resource { } } + // check if we need to get the next set of issues if (! currentPage.hasNext()) { currentPage = getNextIssues().iterator(); } + // return the next item if available if (currentPage.hasNext()) { return currentPage.next(); } else { @@ -605,6 +615,14 @@ public class Issue extends Resource { } } + /** + * Execute the query to get the next set of issues. + * Also sets the startAt, maxMresults, total and issues fields, + * so that the SearchResult can access them. + * + * @return the next set of issues. + * @throws JiraException + */ private List getNextIssues() throws JiraException { if (issues == null) { startAt = Integer.valueOf(0); @@ -612,14 +630,27 @@ public class Issue extends Resource { startAt = startAt + issues.size(); } - JSON searchResult = executeSearch(restClient, jql, includedFields, expandFields, maxResults, startAt); + JSON result = null; + + try { + URI searchUri = createSearchURI(restclient, jql, includedFields, + expandFields, maxResults, startAt); + result = restclient.get(searchUri); + } catch (Exception ex) { + throw new JiraException("Failed to search issues", ex); + } + + if (!(result instanceof JSONObject)) { + throw new JiraException("JSON payload is malformed"); + } + - Map map = (Map) searchResult; + Map map = (Map) result; this.startAt = Field.getInteger(map.get("startAt")); this.maxResults = Field.getInteger(map.get("maxResults")); this.total = Field.getInteger(map.get("total")); - this.issues = Field.getResourceArray(Issue.class, map.get("issues"), restClient); + this.issues = Field.getResourceArray(Issue.class, map.get("issues"), restclient); return issues; } @@ -633,27 +664,24 @@ public class Issue extends Resource { public int max = 0; public int total = 0; public List issues = null; - private RestClient restClient; + private RestClient restclient; private String jql; private String includedFields; private String expandFields; - private Integer maxResults; private Integer startAt; private IssueIterator issueIterator; - public SearchResult(RestClient restClient, String jql, + public SearchResult(RestClient restclient, String jql, String includedFields, String expandFields, Integer maxResults, Integer startAt) throws JiraException { - this.restClient = restClient; + this.restclient = restclient; this.jql = jql; this.includedFields = includedFields; this.expandFields = expandFields; - this.maxResults = maxResults; - this.startAt = startAt; - initSearchResult(); + initSearchResult(maxResults, start); } - private void initSearchResult() throws JiraException { - this.issueIterator = new IssueIterator(restClient, jql, includedFields, expandFields, maxResults, startAt); + private void initSearchResult(Integer maxResults, Integer start) throws JiraException { + this.issueIterator = new IssueIterator(restclient, jql, includedFields, expandFields, maxResults, startAt); this.issueIterator.hasNext(); this.max = issueIterator.maxResults; this.start = issueIterator.startAt; @@ -1306,26 +1334,11 @@ public class Issue extends Resource { private static JSON executeSearch(RestClient restclient, String jql, String includedFields, String expandFields, Integer maxResults, Integer startAt) throws JiraException { - final String j = jql; JSON result = null; try { - Map queryParams = new HashMap(); - queryParams.put("jql", j); - if(maxResults != null){ - queryParams.put("maxResults", String.valueOf(maxResults)); - } - if (includedFields != null) { - queryParams.put("fields", includedFields); - } - if (expandFields != null) { - queryParams.put("expand", expandFields); - } - if (startAt != null) { - queryParams.put("startAt", String.valueOf(startAt)); - } - - URI searchUri = restclient.buildURI(getBaseUri() + "search", queryParams); + URI searchUri = createSearchURI(restclient, jql, includedFields, + expandFields, maxResults, startAt); result = restclient.get(searchUri); } catch (Exception ex) { throw new JiraException("Failed to search issues", ex); @@ -1337,6 +1350,40 @@ public class Issue extends Resource { return result; } + /** + * Creates the URI to execute a jql search. + * + * @param restclient + * @param jql + * @param includedFields + * @param expandFields + * @param maxResults + * @param startAt + * @return the URI to execute a jql search. + * @throws URISyntaxException + */ + private static URI createSearchURI(RestClient restclient, String jql, + String includedFields, String expandFields, Integer maxResults, + Integer startAt) throws URISyntaxException { + Map queryParams = new HashMap(); + queryParams.put("jql", jql); + if(maxResults != null){ + queryParams.put("maxResults", String.valueOf(maxResults)); + } + if (includedFields != null) { + queryParams.put("fields", includedFields); + } + if (expandFields != null) { + queryParams.put("expand", expandFields); + } + if (startAt != null) { + queryParams.put("startAt", String.valueOf(startAt)); + } + + URI searchUri = restclient.buildURI(getBaseUri() + "search", queryParams); + return searchUri; + } + /** * Reloads issue data from the JIRA server (issue includes all navigable * fields).