001package com.box.sdk; 002 003import java.net.URL; 004import java.text.ParseException; 005import java.util.ArrayList; 006import java.util.Date; 007import java.util.List; 008 009import com.eclipsesource.json.JsonArray; 010import com.eclipsesource.json.JsonObject; 011import com.eclipsesource.json.JsonValue; 012 013/** 014 * Represents a task on Box. Tasks can have a due date and can be assigned to a specific user. 015 */ 016public class BoxTask extends BoxResource { 017 018 private static final URLTemplate TASK_URL_TEMPLATE = new URLTemplate("tasks/%s"); 019 private static final URLTemplate GET_ASSIGNMENTS_URL_TEMPLATE = new URLTemplate("tasks/%s/assignments"); 020 private static final URLTemplate ADD_TASK_ASSIGNMENT_URL_TEMPLATE = new URLTemplate("task_assignments"); 021 022 /** 023 * Constructs a BoxTask for a task with a given ID. 024 * @param api the API connection to be used by the task. 025 * @param id the ID of the task. 026 */ 027 public BoxTask(BoxAPIConnection api, String id) { 028 super(api, id); 029 } 030 031 /** 032 * Deletes this task. 033 */ 034 public void delete() { 035 URL url = TASK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 036 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 037 BoxAPIResponse response = request.send(); 038 response.disconnect(); 039 } 040 041 /** 042 * Adds a new assignment to this task. 043 * @param assignTo the user to assign the assignment to. 044 * @return information about the newly added task assignment. 045 */ 046 public BoxTaskAssignment.Info addAssignment(BoxUser assignTo) { 047 JsonObject taskJSON = new JsonObject(); 048 taskJSON.add("type", "task"); 049 taskJSON.add("id", this.getID()); 050 051 JsonObject assignToJSON = new JsonObject(); 052 assignToJSON.add("id", assignTo.getID()); 053 054 JsonObject requestJSON = new JsonObject(); 055 requestJSON.add("task", taskJSON); 056 requestJSON.add("assign_to", assignToJSON); 057 058 URL url = ADD_TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL()); 059 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 060 request.setBody(requestJSON.toString()); 061 BoxJSONResponse response = (BoxJSONResponse) request.send(); 062 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 063 064 BoxTaskAssignment addedAssignment = new BoxTaskAssignment(this.getAPI(), responseJSON.get("id").asString()); 065 return addedAssignment.new Info(responseJSON); 066 } 067 068 /** 069 * Gets any assignments for this task. 070 * @return a list of assignments for this task. 071 */ 072 public List<BoxTaskAssignment.Info> getAssignments() { 073 URL url = GET_ASSIGNMENTS_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 074 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 075 BoxJSONResponse response = (BoxJSONResponse) request.send(); 076 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 077 078 int totalCount = responseJSON.get("total_count").asInt(); 079 List<BoxTaskAssignment.Info> assignments = new ArrayList<BoxTaskAssignment.Info>(totalCount); 080 JsonArray entries = responseJSON.get("entries").asArray(); 081 for (JsonValue value : entries) { 082 JsonObject assignmentJSON = value.asObject(); 083 BoxTaskAssignment assignment = new BoxTaskAssignment(this.getAPI(), assignmentJSON.get("id").asString()); 084 BoxTaskAssignment.Info info = assignment.new Info(assignmentJSON); 085 assignments.add(info); 086 } 087 088 return assignments; 089 } 090 091 /** 092 * Gets information about this task. 093 * @return info about this task. 094 */ 095 public Info getInfo() { 096 URL url = TASK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 097 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 098 BoxJSONResponse response = (BoxJSONResponse) request.send(); 099 JsonObject responseJSON = JsonObject.readFrom(response.getJSON()); 100 return new Info(responseJSON); 101 } 102 103 /** 104 * Updates the information about this task with any info fields that have been modified locally. 105 * 106 * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following 107 * code won't update any information (or even send a network request) since none of the info's fields were 108 * changed:</p> 109 * 110 * <pre>BoxTask task = new BoxTask(api, id); 111 *BoxTask.Info info = task.getInfo(); 112 *task.updateInfo(info);</pre> 113 * 114 * @param info the updated info. 115 */ 116 public void updateInfo(BoxTask.Info info) { 117 URL url = TASK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 118 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 119 request.setBody(info.getPendingChanges()); 120 BoxJSONResponse response = (BoxJSONResponse) request.send(); 121 JsonObject jsonObject = JsonObject.readFrom(response.getJSON()); 122 info.update(jsonObject); 123 } 124 125 /** 126 * Contains information about a BoxTask. 127 */ 128 public class Info extends BoxResource.Info { 129 private BoxFile.Info item; 130 private Date dueAt; 131 private Action action; 132 private String message; 133 private List<BoxTaskAssignment.Info> taskAssignments; 134 private boolean completed; 135 private BoxUser.Info createdBy; 136 private Date createdAt; 137 138 /** 139 * Constructs an empty Info object. 140 */ 141 public Info() { 142 super(); 143 } 144 145 /** 146 * Constructs an Info object by parsing information from a JSON string. 147 * @param json the JSON string to parse. 148 */ 149 public Info(String json) { 150 super(json); 151 } 152 153 /** 154 * Constructs an Info object using an already parsed JSON object. 155 * @param jsonObject the parsed JSON object. 156 */ 157 Info(JsonObject jsonObject) { 158 super(jsonObject); 159 } 160 161 @Override 162 public BoxResource getResource() { 163 return BoxTask.this; 164 } 165 166 /** 167 * Gets the file associated with this task. 168 * @return the file associated with this task. 169 */ 170 public BoxFile.Info getItem() { 171 return this.item; 172 } 173 174 /** 175 * Gets the date at which this task is due. 176 * @return the date at which this task is due. 177 */ 178 public Date getDueAt() { 179 return this.dueAt; 180 } 181 182 /** 183 * Gets the action the task assignee will be prompted to do. 184 * @return the action the task assignee will be prompted to do. 185 */ 186 public Action getAction() { 187 return this.action; 188 } 189 190 /** 191 * Gets the message that will be included with this task. 192 * @return the message that will be included with this task. 193 */ 194 public String getMessage() { 195 return this.message; 196 } 197 198 /** 199 * Gets the collection of task assignments associated with this task. 200 * @return the collection of task assignments associated with this task. 201 */ 202 public List<BoxTaskAssignment.Info> getTaskAssignments() { 203 return this.taskAssignments; 204 } 205 206 /** 207 * Gets whether or not this task has been completed. 208 * @return whether or not this task has been completed. 209 */ 210 public boolean isCompleted() { 211 return this.completed; 212 } 213 214 /** 215 * Gets the user who created this task. 216 * @return the user who created this task. 217 */ 218 public BoxUser.Info getCreatedBy() { 219 return this.createdBy; 220 } 221 222 /** 223 * Gets when this task was created. 224 * @return when this task was created. 225 */ 226 public Date getCreatedAt() { 227 return this.createdAt; 228 } 229 230 @Override 231 void parseJSONMember(JsonObject.Member member) { 232 super.parseJSONMember(member); 233 234 String memberName = member.getName(); 235 JsonValue value = member.getValue(); 236 try { 237 if (memberName.equals("item")) { 238 JsonObject itemJSON = value.asObject(); 239 String itemID = itemJSON.get("id").asString(); 240 BoxFile file = new BoxFile(getAPI(), itemID); 241 this.item = file.new Info(itemJSON); 242 } else if (memberName.equals("due_at")) { 243 this.dueAt = BoxDateFormat.parse(value.asString()); 244 } else if (memberName.equals("action")) { 245 this.action = Action.fromJSONString(value.asString()); 246 } else if (memberName.equals("message")) { 247 this.message = value.asString(); 248 } else if (memberName.equals("task_assignment_collection")) { 249 this.taskAssignments = this.parseTaskAssignmentCollection(value.asObject()); 250 } else if (memberName.equals("is_completed")) { 251 this.completed = value.asBoolean(); 252 } else if (memberName.equals("created_by")) { 253 JsonObject userJSON = value.asObject(); 254 String userID = userJSON.get("id").asString(); 255 BoxUser user = new BoxUser(getAPI(), userID); 256 this.createdBy = user.new Info(userJSON); 257 } else if (memberName.equals("created_at")) { 258 this.createdAt = BoxDateFormat.parse(value.asString()); 259 } 260 261 } catch (ParseException e) { 262 assert false : "A ParseException indicates a bug in the SDK."; 263 } 264 } 265 266 private List<BoxTaskAssignment.Info> parseTaskAssignmentCollection(JsonObject jsonObject) { 267 int count = jsonObject.get("total_count").asInt(); 268 List<BoxTaskAssignment.Info> taskAssignmentCollection = new ArrayList<BoxTaskAssignment.Info>(count); 269 JsonArray entries = jsonObject.get("entries").asArray(); 270 for (JsonValue value : entries) { 271 JsonObject entry = value.asObject(); 272 String id = entry.get("id").asString(); 273 BoxTaskAssignment assignment = new BoxTaskAssignment(getAPI(), id); 274 taskAssignmentCollection.add(assignment.new Info(entry)); 275 } 276 277 return taskAssignmentCollection; 278 } 279 } 280 281 /** 282 * Enumerates the possible actions that a task can have. 283 */ 284 public enum Action { 285 /** 286 * The task must be reviewed. 287 */ 288 REVIEW ("review"); 289 290 private final String jsonValue; 291 292 private Action(String jsonValue) { 293 this.jsonValue = jsonValue; 294 } 295 296 static Action fromJSONString(String jsonValue) { 297 if (jsonValue.equals("review")) { 298 return REVIEW; 299 } else { 300 throw new IllegalArgumentException("The provided JSON value isn't a valid Action."); 301 } 302 } 303 304 String toJSONString() { 305 return this.jsonValue; 306 } 307 } 308}