1
0
Fork 0

Merge pull request #8 from rcarz/master

unsealed classes for better extendibility
master
Kyle Chaplin 2013-09-29 20:14:54 -07:00
commit a2e6adeced
32 changed files with 122 additions and 33 deletions

View File

@ -107,6 +107,12 @@ public class Example {
}})
.execute();
/* You can also update values with field operations. */
issue.update()
.fieldAdd(Field.LABELS, "baz")
.fieldRemove(Field.LABELS, "foo")
.execute();
/* Print the summary. We have to refresh first to pickup the new value. */
issue.refresh();
System.out.println("New Summary: " + issue.getSummary());
@ -145,6 +151,7 @@ public class Example {
.field("customfield_5678", new HashMap() {{
put("value", "foo");
put("value", "bar");
put("id", "1234"); /* you can also update using the value ID */
}})
.execute();

View File

@ -35,7 +35,7 @@ import org.apache.http.client.methods.HttpGet;
/**
* Represents an issue attachment.
*/
public final class Attachment extends Resource {
public class Attachment extends Resource {
private User author = null;
private String filename = null;

View File

@ -28,7 +28,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue comment.
*/
public final class Comment extends Resource {
public class Comment extends Resource {
private User author = null;
private String body = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue component.
*/
public final class Component extends Resource {
public class Component extends Resource {
private String name = null;
private boolean isAssigneeTypeValid = false;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an custom field option.
*/
public final class CustomFieldOption extends Resource {
public class CustomFieldOption extends Resource {
private String value = null;

View File

@ -50,6 +50,25 @@ public final class Field {
public int customId;
}
/**
* Field update operation.
*/
public static final class Operation {
public String name;
public Object value;
/**
* Initialises a new update operation.
*
* @param name Operation name
* @param value Field value
*/
public Operation(String name, Object value) {
this.name = name;
this.value = value;
}
}
public static final String ASSIGNEE = "assignee";
public static final String ATTACHMENT = "attachment";
public static final String COMMENT = "comment";
@ -442,7 +461,25 @@ public final class Field {
if (!(value instanceof Iterable))
throw new JiraException("Field expects an Iterable value");
return toArray((Iterable)value, m.items);
boolean isOper = false;
for (Object v : (Iterable)value) {
isOper = v instanceof Operation;
break;
}
if (isOper) {
List results = new ArrayList();
for (Object v : (Iterable)value) {
Operation oper = (Operation)v;
JSONObject json = new JSONObject();
json.put(oper.name, oper.value.toString());
results.add(json.toString());
}
return toArray(results, m.items);
} else
return toArray((Iterable)value, m.items);
} else if (m.type.equals("date")) {
Date d = toDate(value);

View File

@ -21,6 +21,7 @@ package net.rcarz.jiraclient;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -33,7 +34,7 @@ import net.sf.json.JSONObject;
/**
* Represents a JIRA issue.
*/
public final class Issue extends Resource {
public class Issue extends Resource {
/**
* Used to chain fields to a create action.
@ -103,6 +104,7 @@ public final class Issue extends Resource {
public final class FluentUpdate {
Map<String, Object> fields = new HashMap<String, Object>();
Map<String, List> fieldOpers = new HashMap<String, List>();
JSONObject editmeta = null;
private FluentUpdate(JSONObject editmeta) {
@ -116,8 +118,9 @@ public final class Issue extends Resource {
*/
public void execute() throws JiraException {
JSONObject fieldmap = new JSONObject();
JSONObject updatemap = new JSONObject();
if (fields.size() == 0)
if (fields.size() == 0 && fieldOpers.size() == 0)
throw new JiraException("No fields were given for update");
for (Map.Entry<String, Object> ent : fields.entrySet()) {
@ -125,8 +128,18 @@ public final class Issue extends Resource {
fieldmap.put(ent.getKey(), newval);
}
for (Map.Entry<String, List> ent : fieldOpers.entrySet()) {
Object newval = Field.toJson(ent.getKey(), ent.getValue(), editmeta);
updatemap.put(ent.getKey(), newval);
}
JSONObject req = new JSONObject();
req.put("fields", fieldmap);
if (fieldmap.size() > 0)
req.put("fields", fieldmap);
if (updatemap.size() > 0)
req.put("update", updatemap);
try {
restclient.put(getRestUri(key), req);
@ -147,6 +160,38 @@ public final class Issue extends Resource {
fields.put(name, value);
return this;
}
private FluentUpdate fieldOperation(String oper, String name, Object value) {
if (!fieldOpers.containsKey(name))
fieldOpers.put(name, new ArrayList());
fieldOpers.get(name).add(new Field.Operation(oper, value));
return this;
}
/**
* Adds a field value to the existing value set.
*
* @param name Name of the field
* @param value Field value to append
*
* @return the current fluent update instance
*/
public FluentUpdate fieldAdd(String name, Object value) {
return fieldOperation("add", name, value);
}
/**
* Removes a field value from the existing value set.
*
* @param name Name of the field
* @param value Field value to remove
*
* @return the current fluent update instance
*/
public FluentUpdate fieldRemove(String name, Object value) {
return fieldOperation("remove", name, value);
}
}
/**

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue link.
*/
public final class IssueLink extends Resource {
public class IssueLink extends Resource {
private LinkType type = null;
private Issue inwardIssue = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue type.
*/
public final class IssueType extends Resource {
public class IssueType extends Resource {
private String description = null;
private String iconUrl = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue link type.
*/
public final class LinkType extends Resource {
public class LinkType extends Resource {
private String name = null;
private String inward = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue priority.
*/
public final class Priority extends Resource {
public class Priority extends Resource {
private String iconUrl = null;
private String name = null;

View File

@ -29,7 +29,7 @@ import net.sf.json.JSONObject;
/**
* Represents a JIRA project.
*/
public final class Project extends Resource {
public class Project extends Resource {
private Map<String, String> avatarUrls = null;
private String key = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue resolution.
*/
public final class Resolution extends Resource {
public class Resolution extends Resource {
private String description = null;
private String name = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue status.
*/
public final class Status extends Resource {
public class Status extends Resource {
private String description = null;
private String iconUrl = null;

View File

@ -26,7 +26,7 @@ import net.sf.json.JSONObject;
/**
* Represents issue time tracking data.
*/
public final class TimeTracking {
public class TimeTracking {
private String originalEstimate = null;
private String remainingEstimate = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents a JIRA user.
*/
public final class User extends Resource {
public class User extends Resource {
private boolean active = false;
private Map<String, String> avatarUrls = null;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents a product version.
*/
public final class Version extends Resource {
public class Version extends Resource {
private String name = null;
private boolean archived = false;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents issue votes.
*/
public final class Votes extends Resource {
public class Votes extends Resource {
private String name = null;
private int votes = 0;

View File

@ -27,7 +27,7 @@ import net.sf.json.JSONObject;
/**
* Represents issue watches.
*/
public final class Watches extends Resource {
public class Watches extends Resource {
private String name = null;
private int watchCount = 0;

View File

@ -28,7 +28,7 @@ import net.sf.json.JSONObject;
/**
* Represents an issue work log.
*/
public final class WorkLog extends Resource {
public class WorkLog extends Resource {
private User author = null;
private String comment = null;

View File

@ -36,7 +36,7 @@ import net.sf.json.JSONObject;
/**
* GreenHopper backlog data.
*/
public final class Backlog {
public class Backlog {
private RestClient restclient = null;
private List<SprintIssue> issues = null;

View File

@ -32,7 +32,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper epic issue.
*/
public final class Epic extends GreenHopperIssue {
public class Epic extends GreenHopperIssue {
public String epicLabel = null;
public String epicColour = null;

View File

@ -28,7 +28,7 @@ import net.sf.json.JSONObject;
/**
* GreenHopper epic statistics.
*/
public final class EpicStats {
public class EpicStats {
private Double notDoneEstimate = null;
private Double doneEstimate = null;

View File

@ -28,7 +28,7 @@ import net.sf.json.JSONObject;
/**
* GreenHopper estimate statistics for rapid views.
*/
public final class EstimateStatistic {
public class EstimateStatistic {
private String statFieldId = null;
private int statFieldValue = 0;

View File

@ -28,7 +28,7 @@ import net.sf.json.JSONObject;
/**
* GreenHopper estimate sum for rapid views.
*/
public final class EstimateSum {
public class EstimateSum {
private Double value = null;
private String text = null;

View File

@ -29,7 +29,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper marker (a sprint that hasn't started).
*/
public final class Marker extends GreenHopperResource {
public class Marker extends GreenHopperResource {
private String name = null;

View File

@ -33,7 +33,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper Rapid Board.
*/
public final class RapidView extends GreenHopperResource {
public class RapidView extends GreenHopperResource {
private String name = null;
private boolean canEdit = false;

View File

@ -31,7 +31,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper JIRA project.
*/
public final class RapidViewProject extends GreenHopperResource {
public class RapidViewProject extends GreenHopperResource {
private String key = null;
private String name = null;

View File

@ -31,7 +31,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper JIRA project version.
*/
public final class RapidViewVersion extends GreenHopperResource {
public class RapidViewVersion extends GreenHopperResource {
private String name = null;
private int sequence = 0;

View File

@ -31,7 +31,7 @@ import org.joda.time.DateTime;
/**
* Represents a GreenHopper sprint.
*/
public final class Sprint extends GreenHopperResource {
public class Sprint extends GreenHopperResource {
private String name = null;
private boolean closed = false;

View File

@ -29,7 +29,7 @@ import net.sf.json.JSONObject;
/**
* Represents a GreenHopper sprint issue.
*/
public final class SprintIssue extends GreenHopperIssue {
public class SprintIssue extends GreenHopperIssue {
private String epic = null;
private EstimateStatistic estimateStatistic = null;

View File

@ -35,7 +35,7 @@ import net.sf.json.JSONObject;
/**
* GreenHopper sprint statistics.
*/
public final class SprintReport {
public class SprintReport {
private RestClient restclient = null;
private Sprint sprint = null;