Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 04f90c0

Browse files
committed
Explode Issue attributes
1 parent cbcf089 commit 04f90c0

22 files changed

+1247
-199
lines changed

README.md

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -279,30 +279,27 @@ public class Example {
279279
https://docs.atlassian.com/jira-software/REST/cloud/
280280

281281
### Agile supported calls ###
282-
1. [AgileClient](src/main/java/net/rcarz/jiraclient/agile/AgileClient.java)
283-
1. GET /rest/agile/1.0/board
284-
1. GET /rest/agile/1.0/board/{boardId}
285-
1. GET /rest/agile/1.0/sprint/{sprintId}
286-
1. GET /rest/agile/1.0/issue/{issueIdOrKey}
287-
1. [Board](src/main/java/net/rcarz/jiraclient/agile/Board.java)
288-
1. GET /rest/agile/1.0/board
289-
1. GET /rest/agile/1.0/board/{boardId}
290-
1. GET /rest/agile/1.0/board/{boardId}/sprint
291-
1. [Sprint](src/main/java/net/rcarz/jiraclient/agile/Sprint.java)
292-
1. GET /rest/agile/1.0/sprint/{sprintId}
293-
1. GET /rest/agile/1.0/board/{boardId}/sprint
294-
1. [Issue](src/main/java/net/rcarz/jiraclient/agile/Issue.java)
295-
1. GET /rest/agile/1.0/issue/{issueIdOrKey}
296-
297-
1. To implement
298-
1. -- GET /rest/agile/1.0/board/{boardId}/backlog
299-
1. -- GET /rest/agile/1.0/board/{boardId}/epic
300-
1. -- GET /rest/agile/1.0/board/{boardId}/epic/{epicId}/issue
301-
1. -- GET /rest/agile/1.0/board/{boardId}/epic/none/issue
302-
1. -- GET /rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
303-
1. -- GET /rest/agile/1.0/epic/{epicIdOrKey}/issue
304-
1. -- GET /rest/agile/1.0/epic/none/issue
305-
1. -- GET /rest/agile/1.0/sprint/{sprintId}/issue
282+
| Class | Method | REST Call |
283+
| ----- | ------ | --------- |
284+
| [AgileClient](src/main/java/net/rcarz/jiraclient/agile/AgileClient.java) | ```List<Board> getBoards()``` | GET /rest/agile/1.0/board |
285+
| | ```Board getBoard(long id)``` | GET /rest/agile/1.0/board/{boardId} |
286+
| | ```Sprint getSprint(long id)``` | GET /rest/agile/1.0/sprint/{sprintId} |
287+
| | ```Epic getEpic(long id)``` | GET /rest/agile/1.0/epic/{epicId} |
288+
| | ```Issue getIssue(long id)``` | GET /rest/agile/1.0/issue/{issueId} |
289+
| | ```Issue getIssue(String key)``` | GET /rest/agile/1.0/issue/{issueKey} |
290+
| [Board](src/main/java/net/rcarz/jiraclient/agile/Board.java) | ``` static List<Board> getAll(RestClient restclient)``` | GET /rest/agile/1.0/board |
291+
| | ```static Board get(RestClient restclient, long id)``` | GET /rest/agile/1.0/board/{boardId} |
292+
| | ```List<Sprint> getSprints()``` | GET /rest/agile/1.0/board/{boardId}/sprint |
293+
| * | ```List<Epic> getEpics()``` | GET /rest/agile/1.0/board/{boardId}/epic
294+
| * | ```List<Issue> getBacklog()``` | GET /rest/agile/1.0/board/{boardId}/backlog
295+
| * | ```List<Issue> getIssuesWithoutEpic()``` | GET /rest/agile/1.0/board/{boardId}/epic/none/issue
296+
| [Sprint](src/main/java/net/rcarz/jiraclient/agile/Sprint.java) | ``` static Sprint get(RestClient restclient, long sprintId)``` | GET /rest/agile/1.0/sprint/{sprintId} |
297+
| | ```static List<Sprint> getAll(RestClient restclient, long boardId)``` | GET /rest/agile/1.0/board/{boardId}/sprint |
298+
| * | ```List<Issue> getIssues()``` | GET /rest/agile/1.0/sprint/{sprintId}/issue |
299+
| [Epic](src/main/java/net/rcarz/jiraclient/agile/Epic.java) | ```static Epic get(RestClient restclient, long id)``` | GET /rest/agile/1.0/epic/{epicId} |
300+
| * | ```List<Issue> getIssues()``` | GET /rest/agile/1.0/epic/{epicId}/issue |
301+
| [Issue](src/main/java/net/rcarz/jiraclient/agile/Issue.java) | ```static Issue get(RestClient restclient, long id)``` | GET /rest/agile/1.0/issue/{issueId} |
302+
| | ```static Issue get(RestClient restclient, String key)``` | GET /rest/agile/1.0/issue/{issueKey} |
306303

307304

308305

src/main/java/net/rcarz/jiraclient/agile/AgileClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
/**
2929
* An Agile extension to the JIRA client.
3030
*
31+
* @author pldupont
3132
* @see "https://docs.atlassian.com/jira-software/REST/cloud/"
3233
*/
3334
public class AgileClient {

src/main/java/net/rcarz/jiraclient/agile/AgileResource.java

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,16 @@
2525
import net.sf.json.JSON;
2626
import net.sf.json.JSONArray;
2727
import net.sf.json.JSONObject;
28-
import org.apache.commons.lang.BooleanUtils;
2928
import org.apache.commons.lang.math.NumberUtils;
3029

3130
import java.lang.reflect.Constructor;
3231
import java.util.ArrayList;
33-
import java.util.HashMap;
3432
import java.util.List;
35-
import java.util.Map;
3633

3734
/**
3835
* A base class for Agile resources.
3936
*
37+
* @author pldupont
4038
* @see "https://docs.atlassian.com/jira-software/REST/cloud/"
4139
*/
4240
public abstract class AgileResource {
@@ -51,15 +49,16 @@ public abstract class AgileResource {
5149
private long id = 0;
5250
private String name;
5351
private String self;
54-
private Map<String, Object> attributes = new HashMap<String, Object>();
52+
private JSONObject attributes = new JSONObject();
5553

5654
/**
5755
* Creates a new Agile resource.
5856
*
5957
* @param restclient REST client instance
6058
* @param json JSON payload
59+
* @throws JiraException when the retrieval fails
6160
*/
62-
public AgileResource(RestClient restclient, JSONObject json) {
61+
public AgileResource(RestClient restclient, JSONObject json) throws JiraException {
6362
this.restclient = restclient;
6463
if (json != null) {
6564
deserialize(json);
@@ -73,8 +72,9 @@ public AgileResource(RestClient restclient, JSONObject json) {
7372
* @param r a JSONObject instance
7473
* @param restclient REST client instance
7574
* @return a Resource instance or null if r isn't a JSONObject instance
75+
* @throws JiraException when the retrieval fails
7676
*/
77-
private static <T extends AgileResource> T getResource(
77+
protected static <T extends AgileResource> T getResource(
7878
Class<T> type, Object r, RestClient restclient) throws JiraException {
7979

8080
if (!(r instanceof JSONObject)) {
@@ -101,26 +101,29 @@ private static <T extends AgileResource> T getResource(
101101
* @param type Resource data type
102102
* @param ra a JSONArray instance
103103
* @param restclient REST client instance
104+
* @param listName The name of the list of items from the JSON result.
104105
* @return a list of Resources found in ra
106+
* @throws JiraException when the retrieval fails
105107
*/
106-
private static <T extends AgileResource> List<T> getResourceArray(
107-
Class<T> type, Object ra, RestClient restclient) throws JiraException {
108+
protected static <T extends AgileResource> List<T> getResourceArray(
109+
Class<T> type, Object ra, RestClient restclient, String listName) throws JiraException {
108110
if (!(ra instanceof JSONObject)) {
109111
throw new JiraException("JSON payload is malformed");
110112
}
111113

112114
JSONObject jo = (JSONObject) ra;
113115

114-
if (!jo.containsKey("values") || !(jo.get("values") instanceof JSONArray)) {
116+
if (!jo.containsKey(listName) || !(jo.get(listName) instanceof JSONArray)) {
115117
throw new JiraException(type.getSimpleName() + " result is malformed");
116118
}
117119

118120
List<T> results = new ArrayList<T>();
119121

120-
for (Object v : (JSONArray) jo.get("values")) {
122+
for (Object v : (JSONArray) jo.get(listName)) {
121123
T item = getResource(type, v, restclient);
122-
if (item != null)
124+
if (item != null) {
123125
results.add(item);
126+
}
124127
}
125128

126129
return results;
@@ -130,10 +133,28 @@ private static <T extends AgileResource> List<T> getResourceArray(
130133
* Retrieves all boards visible to the session user.
131134
*
132135
* @param restclient REST client instance
136+
* @param type The type of the object to deserialize.
137+
* @param url The URL to call.
138+
* @return a list of boards
139+
* @throws JiraException when the retrieval fails
140+
*/
141+
static <T extends AgileResource> List<T> list(
142+
RestClient restclient, Class<T> type, String url) throws JiraException {
143+
return list(restclient, type, url, "values");
144+
}
145+
146+
/**
147+
* Retrieves all boards visible to the session user.
148+
*
149+
* @param restclient REST client instance
150+
* @param type The type of the object to deserialize.
151+
* @param url The URL to call.
152+
* @param listName The name of the list of items in the JSON response.
133153
* @return a list of boards
134154
* @throws JiraException when the retrieval fails
135155
*/
136-
static <T extends AgileResource> List<T> list(RestClient restclient, Class<T> type, String url) throws JiraException {
156+
static <T extends AgileResource> List<T> list(
157+
RestClient restclient, Class<T> type, String url, String listName) throws JiraException {
137158

138159
JSON result;
139160
try {
@@ -145,7 +166,8 @@ static <T extends AgileResource> List<T> list(RestClient restclient, Class<T> ty
145166
return getResourceArray(
146167
type,
147168
result,
148-
restclient
169+
restclient,
170+
listName
149171
);
150172
}
151173

@@ -172,6 +194,44 @@ static <T extends AgileResource> T get(RestClient restclient, Class<T> type, Str
172194
);
173195
}
174196

197+
/**
198+
* Extract from a sub list the Resource array, if present.
199+
*
200+
* @param type Resource data type
201+
* @param subJson a JSONObject instance
202+
* @param resourceName The name of the list of items from the JSON result.
203+
* @param <T> The type of Agile resource to return.
204+
* @return The list of resources if present.
205+
* @throws JiraException when the retrieval fails
206+
*/
207+
<T extends AgileResource> List<T> getSubResourceArray(
208+
Class<T> type, JSONObject subJson, String resourceName) throws JiraException {
209+
List<T> result = null;
210+
if (subJson.containsKey(resourceName)) {
211+
result = getResourceArray(type, subJson.get(resourceName), getRestclient(), resourceName + "s");
212+
}
213+
return result;
214+
}
215+
216+
/**
217+
* Extract from a sub list the Resource, if present.
218+
*
219+
* @param type Resource data type
220+
* @param subJson a JSONObject instance
221+
* @param resourceName The name of the item from the JSON result.
222+
* @param <T> The type of Agile resource to return.
223+
* @return The resource if present.
224+
* @throws JiraException when the retrieval fails
225+
*/
226+
<T extends AgileResource> T getSubResource(
227+
Class<T> type, JSONObject subJson, String resourceName) throws JiraException {
228+
T result = null;
229+
if (subJson.containsKey(resourceName)) {
230+
result = getResource(type, subJson.get(resourceName), getRestclient());
231+
}
232+
return result;
233+
}
234+
175235
/**
176236
* @return Internal JIRA ID.
177237
*/
@@ -186,6 +246,13 @@ public String getName() {
186246
return name;
187247
}
188248

249+
/**
250+
* @param name Setter for the resource name. In some case, the name is called something else.
251+
*/
252+
void setName(String name) {
253+
this.name = name;
254+
}
255+
189256
/**
190257
* @return The resource URL.
191258
*/
@@ -206,47 +273,36 @@ protected RestClient getRestclient() {
206273
* @param name The name of the attribute to retrieve.
207274
* @return The value of the attribute.
208275
*/
209-
String getAttribute(String name) {
276+
public Object getAttribute(String name) {
210277
return (String) attributes.get(name);
211278
}
212279

213-
/**
214-
* Retrieve the specified attribute as a generic object.
215-
*
216-
* @param name The name of the attribute to retrieve.
217-
* @return The value of the attribute.
218-
*/
219-
int getAttributeAsInt(String name) {
220-
return NumberUtils.toInt(getAttribute(name), 0);
221-
}
222-
223-
/**
224-
* Retrieve the specified attribute as a generic object.
225-
*
226-
* @param name The name of the attribute to retrieve.
227-
* @return The value of the attribute.
228-
*/
229-
boolean getAttributeAsBoolean(String name) {
230-
return BooleanUtils.toBoolean(getAttribute(name));
231-
}
232-
233280
/**
234281
* Deserialize the json to extract standard attributes and keep a reference of
235282
* other attributes.
236283
*
237284
* @param json The JSON object to read.
238285
*/
239-
protected void deserialize(JSONObject json) {
286+
void deserialize(JSONObject json) throws JiraException {
240287

241288
id = getLong(json.get("id"));
242289
name = Field.getString(json.get("name"));
243290
self = Field.getString(json.get("self"));
291+
addAttributes(json);
292+
}
293+
294+
/**
295+
* Allow to add more attributes.
296+
*
297+
* @param json The json object to extract attributes from.
298+
*/
299+
void addAttributes(JSONObject json) {
244300
attributes.putAll(json);
245301
}
246302

247303
long getLong(Object o) {
248304
if (o instanceof Integer || o instanceof Long) {
249-
return Field.getInteger(o);
305+
return Field.getLong(o);
250306
} else if (o instanceof String && NumberUtils.isDigits((String) o)) {
251307
return NumberUtils.toLong((String) o, 0L);
252308
} else {

src/main/java/net/rcarz/jiraclient/agile/Board.java

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@
3333
*/
3434
public class Board extends AgileResource {
3535

36-
private static final String ATTR_TYPE = "type";
37-
3836
private String type;
3937

4038
/**
@@ -43,7 +41,7 @@ public class Board extends AgileResource {
4341
* @param restclient REST client instance
4442
* @param json JSON payload
4543
*/
46-
protected Board(RestClient restclient, JSONObject json) {
44+
protected Board(RestClient restclient, JSONObject json) throws JiraException {
4745
super(restclient, json);
4846
}
4947

@@ -71,9 +69,9 @@ public static List<Board> getAll(RestClient restclient) throws JiraException {
7169
}
7270

7371
@Override
74-
protected void deserialize(JSONObject json) {
72+
protected void deserialize(JSONObject json) throws JiraException {
7573
super.deserialize(json);
76-
type = Field.getString(json.get(ATTR_TYPE));
74+
type = Field.getString(json.get("type"));
7775
}
7876

7977
/**
@@ -91,15 +89,28 @@ public List<Sprint> getSprints() throws JiraException {
9189
return Sprint.getAll(getRestclient(), getId());
9290
}
9391

94-
// /**
95-
// * Retrieves the backlog data for this rapid view.
96-
// *
97-
// * @return the backlog
98-
// *
99-
// * @throws JiraException when the retrieval fails
100-
// */
101-
// public Backlog getBacklogData() throws JiraException {
102-
// return Backlog.get(restclient, this);
103-
// }
92+
/**
93+
* @return All issues in the Board backlog.
94+
* @throws JiraException when the retrieval fails
95+
*/
96+
public List<Issue> getBacklog() throws JiraException {
97+
return AgileResource.list(getRestclient(), Issue.class, RESOURCE_URI + "board/" + getId() + "/backlog", "issues");
98+
}
99+
100+
/**
101+
* @return All issues without epic in the Board .
102+
* @throws JiraException when the retrieval fails
103+
*/
104+
public List<Issue> getIssuesWithoutEpic() throws JiraException {
105+
return AgileResource.list(getRestclient(), Issue.class, RESOURCE_URI + "board/" + getId() + "/epic/none/issue", "issues");
106+
}
107+
108+
/**
109+
* @return All epics associated to the Board.
110+
* @throws JiraException when the retrieval fails
111+
*/
112+
public List<Epic> getEpics() throws JiraException {
113+
return AgileResource.list(getRestclient(), Epic.class, RESOURCE_URI + "board/" + getId() + "/epic");
114+
}
104115
}
105116

0 commit comments

Comments
 (0)