1
0
Fork 0

implemented issue creation

master
Bob Carroll 2013-05-26 16:53:12 -07:00
parent 29374abfd7
commit 23044799a7
16 changed files with 337 additions and 46 deletions

View File

@ -22,6 +22,7 @@ package net.rcarz.jiraclient;
import java.util.Date;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -75,7 +76,7 @@ public final class Attachment extends Resource {
public static Attachment get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "attachment/" + id);
@ -83,7 +84,10 @@ public final class Attachment extends Resource {
throw new JiraException("Failed to retrieve attachment " + id, ex);
}
return new Attachment(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Attachment(restclient, (JSONObject)result);
}
@Override

View File

@ -22,6 +22,7 @@ package net.rcarz.jiraclient;
import java.util.Date;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -74,7 +75,7 @@ public final class Comment extends Resource {
public static Comment get(RestClient restclient, String issue, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "issue/" + issue + "/comment/" + id);
@ -82,7 +83,10 @@ public final class Comment extends Resource {
throw new JiraException("Failed to retrieve comment " + id + " on issue " + issue, ex);
}
return new Comment(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Comment(restclient, (JSONObject)result);
}
@Override

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -29,6 +30,7 @@ import net.sf.json.JSONObject;
public final class Component extends Resource {
private String name = null;
private boolean isAssigneeTypeValid = false;
/**
* Creates a component from a JSON payload.
@ -49,6 +51,7 @@ public final class Component extends Resource {
self = Field.getString(map.get("self"));
id = Field.getString(map.get("id"));
name = Field.getString(map.get("name"));
isAssigneeTypeValid = Field.getBoolean(map.get("isAssigneeTypeValid"));
}
/**
@ -64,7 +67,7 @@ public final class Component extends Resource {
public static Component get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "component/" + id);
@ -72,7 +75,10 @@ public final class Component extends Resource {
throw new JiraException("Failed to retrieve component " + id, ex);
}
return new Component(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Component(restclient, (JSONObject)result);
}
@Override
@ -83,5 +89,9 @@ public final class Component extends Resource {
public String getName() {
return name;
}
public boolean isAssigneeTypeValid() {
return isAssigneeTypeValid;
}
}

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -64,7 +65,7 @@ public final class CustomFieldOption extends Resource {
public static CustomFieldOption get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "customFieldOption/" + id);
@ -72,7 +73,10 @@ public final class CustomFieldOption extends Resource {
throw new JiraException("Failed to retrieve custom field option " + id, ex);
}
return new CustomFieldOption(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new CustomFieldOption(restclient, (JSONObject)result);
}
@Override

View File

@ -427,6 +427,11 @@ public final class Field {
JSONObject json = new JSONObject();
json.put("name", value.toString());
return json.toString();
} else if (m.type.equals("project")) {
JSONObject json = new JSONObject();
json.put("key", value.toString());
return json.toString();
} else if (m.type.equals("string")) {
if (value instanceof Map)

View File

@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
@ -33,6 +34,68 @@ import net.sf.json.JSONObject;
*/
public final class Issue extends Resource {
/**
* Used to chain fields to a create action.
*/
public static final class FluentCreate {
Map<String, Object> fields = new HashMap<String, Object>();
RestClient restclient = null;
JSONObject createmeta = null;
private FluentCreate(RestClient restclient, JSONObject createmeta) {
this.restclient = restclient;
this.createmeta = createmeta;
}
/**
* Executes the create action.
*
* @throws JiraException when the create fails
*/
public Issue execute() throws JiraException {
JSONObject fieldmap = new JSONObject();
if (fields.size() == 0)
throw new JiraException("No fields were given for create");
for (Map.Entry<String, Object> ent : fields.entrySet()) {
Object newval = Field.toJson(ent.getKey(), ent.getValue(), createmeta);
fieldmap.put(ent.getKey(), newval);
}
JSONObject req = new JSONObject();
req.put("fields", fieldmap);
JSON result = null;
try {
result = restclient.post(getRestUri(null), req);
} catch (Exception ex) {
throw new JiraException("Failed to create issue", ex);
}
if (!(result instanceof JSONObject) || !((JSONObject)result).containsKey("key") ||
!(((JSONObject)result).get("key") instanceof String))
throw new JiraException("Unexpected result on create issue");
return Issue.get(restclient, (String)((JSONObject)result).get("key"));
}
/**
* Appends a field to the update action.
*
* @param name Name of the field
* @param value New field value
*
* @return the current fluent update instance
*/
public FluentCreate field(String name, Object value) {
fields.put(name, value);
return this;
}
}
/**
* Used to chain fields to an update action.
*/
@ -253,11 +316,51 @@ public final class Issue extends Resource {
}
private static String getRestUri(String key) {
return RESOURCE_URI + "issue/" + key;
return RESOURCE_URI + "issue/" + (key != null ? key : "");
}
private static JSONObject getCreateMetadata(
RestClient restclient, String project, String issueType) throws JiraException {
final String pval = project;
final String itval = issueType;
JSON result = null;
try {
URI createuri = restclient.buildURI(
RESOURCE_URI + "issue/createmeta",
new HashMap<String, String>() {{
put("expand", "projects.issuetypes.fields");
put("projectKeys", pval);
put("issuetypeNames", itval);
}});
result = restclient.get(createuri);
} catch (Exception ex) {
throw new JiraException("Failed to retrieve issue metadata", ex);
}
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
JSONObject jo = (JSONObject)result;
if (jo.isNullObject() || !jo.containsKey("projects") ||
!(jo.get("projects") instanceof JSONArray))
throw new JiraException("Create metadata is malformed");
List<Project> projects = Field.getResourceArray(
Project.class,
(JSONArray)jo.get("projects"),
restclient);
if (projects.isEmpty() || projects.get(0).getIssueTypes().isEmpty())
throw new JiraException("Project or issue type missing from create metadata");
return projects.get(0).getIssueTypes().get(0).getFields();
}
private JSONObject getEditMetadata() throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(getRestUri(key) + "/editmeta");
@ -265,15 +368,20 @@ public final class Issue extends Resource {
throw new JiraException("Failed to retrieve issue metadata", ex);
}
if (result.isNullObject() || !result.containsKey("fields") ||
!(result.get("fields") instanceof JSONObject))
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
JSONObject jo = (JSONObject)result;
if (jo.isNullObject() || !jo.containsKey("fields") ||
!(jo.get("fields") instanceof JSONObject))
throw new JiraException("Edit metadata is malformed");
return (JSONObject)result.get("fields");
return (JSONObject)jo.get("fields");
}
private JSONArray getTransitions() throws JiraException {
JSONObject result = null;
JSON result = null;
try {
URI transuri = restclient.buildURI(
@ -286,11 +394,13 @@ public final class Issue extends Resource {
throw new JiraException("Failed to retrieve transitions", ex);
}
if (result.isNullObject() || !result.containsKey("transitions") ||
!(result.get("transitions") instanceof JSONArray))
throw new JiraException("Transition metadata is missing from results");
JSONObject jo = (JSONObject)result;
return (JSONArray)result.get("transitions");
if (jo.isNullObject() || !jo.containsKey("transitions") ||
!(jo.get("transitions") instanceof JSONArray))
throw new JiraException("Transition metadata is missing from jos");
return (JSONArray)jo.get("transitions");
}
/**
@ -334,6 +444,29 @@ public final class Issue extends Resource {
}
}
/**
* Creates a new JIRA issue.
*
* @param restclient REST client instance
* @param project Key of the project to create the issue in
* @param issueType Name of the issue type to create
*
* @return a fluent create instance
*
* @throws JiraException when the client fails to retrieve issue metadata
*/
public static FluentCreate create(RestClient restclient, String project, String issueType)
throws JiraException {
FluentCreate fc = new FluentCreate(
restclient,
getCreateMetadata(restclient, project, issueType));
return fc
.field(Field.PROJECT, project)
.field(Field.ISSUE_TYPE, issueType);
}
/**
* Retrieves the given issue record.
*
@ -347,7 +480,7 @@ public final class Issue extends Resource {
public static Issue get(RestClient restclient, String key)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(getRestUri(key));
@ -355,7 +488,10 @@ public final class Issue extends Resource {
throw new JiraException("Failed to retrieve issue " + key, ex);
}
return new Issue(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Issue(restclient, (JSONObject)result);
}
/**

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -32,6 +33,7 @@ public final class IssueType extends Resource {
private String iconUrl = null;
private String name = null;
private boolean subtask = false;
private JSONObject fields = null;
/**
* Creates an issue type from a JSON payload.
@ -55,6 +57,9 @@ public final class IssueType extends Resource {
iconUrl = Field.getString(map.get("iconUrl"));
name = Field.getString(map.get("name"));
subtask = Field.getBoolean(map.get("subtask"));
if (map.containsKey("fields") && map.get("fields") instanceof JSONObject)
fields = (JSONObject)map.get("fields");
}
/**
@ -70,7 +75,7 @@ public final class IssueType extends Resource {
public static IssueType get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "issuetype/" + id);
@ -78,7 +83,10 @@ public final class IssueType extends Resource {
throw new JiraException("Failed to retrieve issue type " + id, ex);
}
return new IssueType(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new IssueType(restclient, (JSONObject)result);
}
@Override
@ -101,5 +109,9 @@ public final class IssueType extends Resource {
public boolean isSubtask() {
return subtask;
}
public JSONObject getFields() {
return fields;
}
}

View File

@ -62,6 +62,22 @@ public class JiraClient {
restclient = new RestClient(httpclient, URI.create(uri));
}
/**
* Creates a new issue in the given project.
*
* @param project Key of the project to create in
* @param issueType Name of the issue type to create
*
* @return a fluent create instance
*
* @throws JiraException when something goes wrong
*/
public Issue.FluentCreate createIssue(String project, String issueType)
throws JiraException {
return Issue.create(restclient, project, issueType);
}
/**
* Retreives the issue with the given key.
*

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -66,7 +67,7 @@ public final class Priority extends Resource {
public static Priority get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "priority/" + id);
@ -74,7 +75,10 @@ public final class Priority extends Resource {
throw new JiraException("Failed to retrieve priority " + id, ex);
}
return new Priority(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Priority(restclient, (JSONObject)result);
}
@Override

View File

@ -19,8 +19,11 @@
package net.rcarz.jiraclient;
import java.util.List;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
/**
@ -31,6 +34,13 @@ public final class Project extends Resource {
private Map<String, String> avatarUrls = null;
private String key = null;
private String name = null;
private String description = null;
private User lead = null;
private String assigneeType = null;
private List<Component> components = null;
private List<IssueType> issueTypes = null;
private List<Version> versions = null;
private Map<String, String> roles = null;
/**
* Creates a project from a JSON payload.
@ -53,6 +63,16 @@ public final class Project extends Resource {
avatarUrls = Field.getMap(String.class, String.class, map.get("avatarUrls"));
key = Field.getString(map.get("key"));
name = Field.getString(map.get("name"));
description = Field.getString(map.get("description"));
lead = Field.getResource(User.class, map.get("lead"), restclient);
assigneeType = Field.getString(map.get("assigneeType"));
components = Field.getResourceArray(Component.class, map.get("components"), restclient);
issueTypes = Field.getResourceArray(
IssueType.class,
map.containsKey("issueTypes") ? map.get("issueTypes") : map.get("issuetypes"),
restclient);
versions = Field.getResourceArray(Version.class, map.get("versions"), restclient);
roles = Field.getMap(String.class, String.class, map.get("roles"));
}
/**
@ -68,7 +88,7 @@ public final class Project extends Resource {
public static Project get(RestClient restclient, String key)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "project/" + key);
@ -76,7 +96,34 @@ public final class Project extends Resource {
throw new JiraException("Failed to retrieve project " + key, ex);
}
return new Project(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Project(restclient, (JSONObject)result);
}
/**
* Retrieves all project records visible to the session user.
*
* @param restclient REST client instance
*
* @return a list of projects
*
* @throws JiraException when the retrieval fails
*/
public static List<Project> getAll(RestClient restclient) throws JiraException {
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "project");
} catch (Exception ex) {
throw new JiraException("Failed to retrieve projects", ex);
}
if (!(result instanceof JSONArray))
throw new JiraException("JSON payload is malformed");
return Field.getResourceArray(Project.class, result, restclient);
}
@Override
@ -95,5 +142,33 @@ public final class Project extends Resource {
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public User getLead() {
return lead;
}
public String getAssigneeType() {
return assigneeType;
}
public List<Component> getComponents() {
return components;
}
public List<IssueType> getIssueTypes() {
return issueTypes;
}
public List<Version> getVersions() {
return versions;
}
public Map<String, String> getRoles() {
return roles;
}
}

View File

@ -41,7 +41,8 @@ import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import net.sf.json.JSONObject;
import net.sf.json.JSON;
import net.sf.json.JSONSerializer;
/**
* A simple REST client that speaks JSON.
@ -97,7 +98,7 @@ public class RestClient {
return ub.build();
}
private JSONObject request(HttpRequestBase req) throws RestException, IOException {
private JSON request(HttpRequestBase req) throws RestException, IOException {
req.addHeader("Accept", "application/json");
HttpResponse resp = httpclient.execute(req);
@ -117,10 +118,10 @@ public class RestClient {
if (sl.getStatusCode() >= 300)
throw new RestException(sl.getReasonPhrase(), sl.getStatusCode(), result.toString());
return result.length() > 0 ? JSONObject.fromObject(result.toString()) : null;
return result.length() > 0 ? JSONSerializer.toJSON(result.toString()): null;
}
private JSONObject request(HttpEntityEnclosingRequestBase req, JSONObject payload)
private JSON request(HttpEntityEnclosingRequestBase req, JSON payload)
throws RestException, IOException {
StringEntity ent = null;
@ -148,7 +149,7 @@ public class RestClient {
* @throws RestException when an HTTP-level error occurs
* @throws IOException when an error reading the response occurs
*/
public JSONObject get(URI uri) throws RestException, IOException {
public JSON get(URI uri) throws RestException, IOException {
return request(new HttpGet(uri));
}
@ -163,7 +164,7 @@ public class RestClient {
* @throws IOException when an error reading the response occurs
* @throws URISyntaxException when an error occurred appending the path to the URI
*/
public JSONObject get(String path) throws RestException, IOException, URISyntaxException {
public JSON get(String path) throws RestException, IOException, URISyntaxException {
return get(buildURI(path));
}
@ -178,7 +179,7 @@ public class RestClient {
* @throws RestException when an HTTP-level error occurs
* @throws IOException when an error reading the response occurs
*/
public JSONObject post(URI uri, JSONObject payload) throws RestException, IOException {
public JSON post(URI uri, JSON payload) throws RestException, IOException {
return request(new HttpPost(uri), payload);
}
@ -194,7 +195,7 @@ public class RestClient {
* @throws IOException when an error reading the response occurs
* @throws URISyntaxException when an error occurred appending the path to the URI
*/
public JSONObject post(String path, JSONObject payload)
public JSON post(String path, JSON payload)
throws RestException, IOException, URISyntaxException {
return post(buildURI(path), payload);
@ -211,7 +212,7 @@ public class RestClient {
* @throws RestException when an HTTP-level error occurs
* @throws IOException when an error reading the response occurs
*/
public JSONObject put(URI uri, JSONObject payload) throws RestException, IOException {
public JSON put(URI uri, JSON payload) throws RestException, IOException {
return request(new HttpPut(uri), payload);
}
@ -227,7 +228,7 @@ public class RestClient {
* @throws IOException when an error reading the response occurs
* @throws URISyntaxException when an error occurred appending the path to the URI
*/
public JSONObject put(String path, JSONObject payload)
public JSON put(String path, JSON payload)
throws RestException, IOException, URISyntaxException {
return put(buildURI(path), payload);

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -68,7 +69,7 @@ public final class Status extends Resource {
public static Status get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "status/" + id);
@ -76,7 +77,10 @@ public final class Status extends Resource {
throw new JiraException("Failed to retrieve status " + id, ex);
}
return new Status(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Status(restclient, (JSONObject)result);
}
@Override

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -72,7 +73,7 @@ public final class User extends Resource {
public static User get(RestClient restclient, String username)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "user?username=" + username);
@ -80,7 +81,10 @@ public final class User extends Resource {
throw new JiraException("Failed to retrieve user " + username, ex);
}
return new User(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new User(restclient, (JSONObject)result);
}
@Override

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -68,7 +69,7 @@ public final class Version extends Resource {
public static Version get(RestClient restclient, String id)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "version/" + id);
@ -76,7 +77,10 @@ public final class Version extends Resource {
throw new JiraException("Failed to retrieve version " + id, ex);
}
return new Version(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Version(restclient, (JSONObject)result);
}
@Override

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -67,7 +68,7 @@ public final class Votes extends Resource {
public static Votes get(RestClient restclient, String issue)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "issue/" + issue + "/votes");
@ -75,7 +76,10 @@ public final class Votes extends Resource {
throw new JiraException("Failed to retrieve votes for issue " + issue, ex);
}
return new Votes(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Votes(restclient, (JSONObject)result);
}
@Override

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.util.Map;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
/**
@ -67,7 +68,7 @@ public final class Watches extends Resource {
public static Watches get(RestClient restclient, String issue)
throws JiraException {
JSONObject result = null;
JSON result = null;
try {
result = restclient.get(RESOURCE_URI + "issue/" + issue + "/watches");
@ -75,7 +76,10 @@ public final class Watches extends Resource {
throw new JiraException("Failed to retrieve watches for issue " + issue, ex);
}
return new Watches(restclient, result);
if (!(result instanceof JSONObject))
throw new JiraException("JSON payload is malformed");
return new Watches(restclient, (JSONObject)result);
}
@Override