1
0
Fork 0

implemented updating of most system fields

master
Bob Carroll 2013-05-21 13:28:53 -07:00
parent a884bb8a22
commit a02ac414c1
4 changed files with 232 additions and 5 deletions

View File

@ -3,7 +3,7 @@
<groupId>net.rcarz</groupId>
<artifactId>jira-client</artifactId>
<version>1.0-SNAPSHOT</version>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<repositories>

View File

@ -19,6 +19,7 @@
package net.rcarz.jiraclient;
import java.lang.Iterable;
import java.lang.UnsupportedOperationException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
@ -36,6 +37,19 @@ import net.sf.json.JSONObject;
*/
public final class Field {
/**
* Field metadata structure.
*/
public static final class Meta {
public boolean required;
public String type;
public String items;
public String name;
public String system;
public String custom;
public int customId;
}
public static final String ASSIGNEE = "assignee";
public static final String ATTACHMENT = "attachment";
public static final String COMMENT = "comment";
@ -52,6 +66,8 @@ public final class Field {
public static final String TIME_TRACKING = "timetracking";
public static final String VERSIONS = "versions";
public static final String DATE_FORMAT = "yyyy-MM-dd";
private Field() { }
/**
@ -98,7 +114,7 @@ public final class Field {
Date result = null;
if (d instanceof String) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
result = df.parse((String)d, new ParsePosition(0));
}
@ -271,5 +287,138 @@ public final class Field {
return result;
}
/**
* Extracts field metadata from an editmeta JSON object.
*
* @param name Field name
* @param editmeta Edit metadata JSON object
*
* @return a Meta instance with field metadata
*
* @throws JiraException when the field is missing or metadata is bad
*/
public static Meta getFieldMetadata(String name, JSONObject editmeta)
throws JiraException {
if (editmeta.isNullObject() || !editmeta.containsKey("fields"))
throw new JiraException("Edit metadata is malformed");
Map fields = (Map)editmeta.get("fields");
if (!fields.containsKey(name))
throw new JiraException("Field '" + name + "' does not exist or read-only");
Map f = (Map)fields.get(name);
Meta m = new Meta();
m.required = Field.getBoolean(f.get("required"));
m.name = Field.getString(f.get("name"));
if (!f.containsKey("schema"))
throw new JiraException("Field '" + name + "' is missing schema metadata");
Map schema = (Map)f.get("schema");
m.type = Field.getString(schema.get("type"));
m.items = Field.getString(schema.get("items"));
m.system = Field.getString(schema.get("system"));
m.custom = Field.getString(schema.get("custom"));
m.customId = Field.getInteger(schema.get("customId"));
return m;
}
/**
* Converts the given value to a date.
*
* @param value New field value
*
* @return a Date instance or null
*/
public static Date toDate(Object value) {
if (value instanceof Date || value == null)
return (Date)value;
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
return df.parse(value.toString(), new ParsePosition(0));
}
/**
* Converts an iterable type to a JSON array.
*
* @param iter Iterable type containing field values
* @param type Name of the item type
*
* @return a JSON-encoded array of items
*/
public static JSONArray toArray(Iterable iter, String type) throws JiraException {
JSONArray result = new JSONArray();
if (type == null)
throw new JiraException("Array field metadata is missing item type");
for (Object val : iter) {
if (type.equals("component") || type.equals("group") ||
type.equals("user") || type.equals("version")) {
JSONObject json = new JSONObject();
json.put("name", val.toString());
result.add(json.toString());
} else if (type.equals("string"))
result.add(val.toString());
}
return result;
}
/**
* Converts the given value to a JSON object.
*
* @param name Field name
* @param value New field value
* @param editmeta Edit metadata JSON object
*
* @return a JSON-encoded field value
*
* @throws JiraException when a value is bad or field has invalid metadata
* @throws UnsupportedOperationException when a field type isn't supported
*/
public static Object toJson(String name, Object value, JSONObject editmeta)
throws JiraException, UnsupportedOperationException {
if (value == null)
return null;
Meta m = getFieldMetadata(name, editmeta);
if (m.type == null)
throw new JiraException("Field metadata is missing a type");
if (m.type.equals("array")) {
if (!(value instanceof Iterable))
throw new JiraException("Field expects an Iterable value");
return toArray((Iterable)value, m.items);
} else if (m.type.equals("date")) {
Date d = toDate(value);
if (d == null)
throw new JiraException("Field expects a date value or format is invalid");
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
return df.format(d);
} else if (m.type.equals("issuetype") || m.type.equals("priority") || m.type.equals("user")) {
JSONObject json = new JSONObject();
json.put("name", value.toString());
return json.toString();
} else if (m.type.equals("string")) {
return value.toString();
}
throw new UnsupportedOperationException(m.type + " is not a supported field type");
}
}

View File

@ -31,6 +31,58 @@ import net.sf.json.JSONObject;
*/
public final class Issue extends Resource {
/**
* Used to chain fields to an update action.
*/
public final class FluentUpdate {
Map<String, Object> fields = new HashMap<String, Object>();
JSONObject editmeta = null;
private FluentUpdate(JSONObject editmeta) {
this.editmeta = editmeta;
}
/**
* Executes the update action.
*
* @throws JiraException when the update fails
*/
public void execute() throws JiraException {
JSONObject fieldmap = new JSONObject();
if (fields.size() == 0)
throw new JiraException("No fields were given for update");
for (Map.Entry<String, Object> ent : fields.entrySet()) {
Object newval = Field.toJson(ent.getKey(), ent.getValue(), editmeta);
fieldmap.put(ent.getKey(), newval);
}
JSONObject req = new JSONObject();
req.put("fields", fieldmap);
try {
restclient.put(getRestUri(key), req);
} catch (Exception ex) {
throw new JiraException("Failed to update issue " + key, ex);
}
}
/**
* 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 FluentUpdate field(String name, Object value) {
fields.put(name, value);
return this;
}
}
private String key = null;
/* system fields */
@ -89,6 +141,22 @@ public final class Issue extends Resource {
versions = Field.getResourceArray(Version.class, fields.get(Field.VERSIONS), restclient);
}
private static String getRestUri(String key) {
return RESOURCE_URI + "issue/" + key;
}
private JSONObject getEditMetadata() throws JiraException {
JSONObject result = null;
try {
result = restclient.get(getRestUri(key) + "/editmeta");
} catch (Exception ex) {
throw new JiraException("Failed to retrieve issue metadata", ex);
}
return result;
}
/**
* Retrieves the given issue record.
*
@ -105,7 +173,7 @@ public final class Issue extends Resource {
JSONObject result = null;
try {
result = restclient.get(RESOURCE_URI + "issue/" + key);
result = restclient.get(getRestUri(key));
} catch (Exception ex) {
throw new JiraException("Failed to retrieve issue " + key, ex);
}
@ -113,6 +181,17 @@ public final class Issue extends Resource {
return new Issue(restclient, result);
}
/**
* Begins an update field chain.
*
* @return a fluent update instance
*
* @throws JiraException when the client fails to retrieve issue metadata
*/
public FluentUpdate update() throws JiraException {
return new FluentUpdate(getEditMetadata());
}
@Override
public String toString() {
return getKey();

View File

@ -45,8 +45,7 @@ public class RestException extends Exception {
}
public String getMessage() {
String msg = "%s: %s: %s";
return msg.format(Integer.toString(status), super.getMessage(), result);
return String.format("%s %s: %s", Integer.toString(status), super.getMessage(), result);
}
}