001package com.box.sdk;
002
003import java.net.URL;
004import java.text.ParseException;
005import java.util.Date;
006
007import com.eclipsesource.json.JsonObject;
008import com.eclipsesource.json.JsonValue;
009
010/**
011 * Represents a task assignment on Box, which can be used to assign a task to a single user. There can be multiple
012 * assignments on a single task.
013 */
014public class BoxTaskAssignment extends BoxResource {
015
016    private static final URLTemplate TASK_ASSIGNMENT_URL_TEMPLATE = new URLTemplate("tasks_assignments/%s");
017
018    /**
019     * Constructs a BoxTaskAssignment for a task assignment with a given ID.
020     *
021     * @param api the API connection to be used by the resource.
022     * @param id  the ID of the task assignment.
023     */
024    public BoxTaskAssignment(BoxAPIConnection api, String id) {
025        super(api, id);
026    }
027
028    /**
029     * Deletes this task assignment.
030     */
031    public void delete() {
032        URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
033        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
034        BoxAPIResponse response = request.send();
035        response.disconnect();
036    }
037
038    /**
039     * Gets information about this task assignment.
040     * @return info about this task assignment.
041     */
042    public Info getInfo() {
043        URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
044        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
045        BoxJSONResponse response = (BoxJSONResponse) request.send();
046        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
047        return new Info(responseJSON);
048    }
049
050    /**
051     * Updates the information about this task assignment with any info fields that have been modified locally.
052     *
053     * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following
054     * code won't update any information (or even send a network request) since none of the info's fields were
055     * changed:</p>
056     *
057     * <pre>BoxTaskAssignment taskAssignment = new BoxTaskAssignment(api, id);
058     *BoxTaskAssignment.Info info = taskAssignment.getInfo();
059     *taskAssignment.updateInfo(info);</pre>
060     *
061     * @param info the updated info.
062     */
063    public void updateInfo(BoxTask.Info info) {
064        URL url = TASK_ASSIGNMENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
065        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
066        request.setBody(info.getPendingChanges());
067        BoxJSONResponse response = (BoxJSONResponse) request.send();
068        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
069        info.update(jsonObject);
070    }
071
072    /**
073     * Contains information about a task assignment.
074     */
075    public class Info extends BoxResource.Info {
076        private BoxItem.Info item;
077        private BoxUser.Info assignedTo;
078        private String message;
079        private Date completedAt;
080        private Date assignedAt;
081        private Date remindedAt;
082        private ResolutionState resolutionState;
083        private BoxUser.Info assignedBy;
084
085        /**
086         * Constructs an empty Info object.
087         */
088        public Info() {
089            super();
090        }
091
092        /**
093         * Constructs an Info object by parsing information from a JSON string.
094         * @param  json the JSON string to parse.
095         */
096        public Info(String json) {
097            super(json);
098        }
099
100        /**
101         * Constructs an Info object using an already parsed JSON object.
102         * @param  jsonObject the parsed JSON object.
103         */
104        Info(JsonObject jsonObject) {
105            super(jsonObject);
106        }
107
108        @Override
109        public BoxResource getResource() {
110            return BoxTaskAssignment.this;
111        }
112
113        /**
114         * Gets the item associated with this task.
115         * @return the item associated with this task.
116         */
117        public BoxItem.Info getItem() {
118            return this.item;
119        }
120
121        /**
122         * Gets the user the assignment is assigned to.
123         * @return the user assigned to this assignment.
124         */
125        public BoxUser.Info getAssignedTo() {
126            return this.assignedTo;
127        }
128
129        /**
130         * Gets the message that will be included with this task assignment.
131         * @return the message that will be included with this task assignment.
132         */
133        public String getMessage() {
134            return this.message;
135        }
136
137        /**
138         * Gets the date the assignment is to be completed at.
139         * @return the date the assignment is to be completed at.
140         */
141        public Date getCompletedAt() {
142            return this.completedAt;
143        }
144
145        /**
146         * Gets the date the assignment was assigned at.
147         * @return the date the assignment was assigned at.
148         */
149        public Date getAssignedAt() {
150            return this.assignedAt;
151        }
152
153        /**
154         * Gets the date the assignee is to be reminded at.
155         * @return the date the assignee is to be reminded at.
156         */
157        public Date getRemindedAt() {
158            return this.remindedAt;
159        }
160
161        /**
162         * Gets the current resolution state of the assignment.
163         * @return the current resolution state of the assignment.
164         */
165        public ResolutionState getResolutionState() {
166            return this.resolutionState;
167        }
168
169        /**
170         * Gets the user that assigned the assignment.
171         * @return the user that assigned the assignment.
172         */
173        public BoxUser.Info getAssignedBy() {
174            return this.assignedBy;
175        }
176
177        @Override
178        void parseJSONMember(JsonObject.Member member) {
179            super.parseJSONMember(member);
180
181            String memberName = member.getName();
182            JsonValue value = member.getValue();
183            try {
184                if (memberName.equals("item")) {
185                    JsonObject itemJSON = value.asObject();
186                    String itemID = itemJSON.get("id").asString();
187                    BoxFile file = new BoxFile(getAPI(), itemID);
188                    this.item = file.new Info(itemJSON);
189                } else if (memberName.equals("assigned_to")) {
190                    JsonObject userJSON = value.asObject();
191                    String userID = userJSON.get("id").asString();
192                    BoxUser user = new BoxUser(getAPI(), userID);
193                    this.assignedTo = user.new Info(userJSON);
194                } else if (memberName.equals("message")) {
195                    this.message = value.asString();
196                } else if (memberName.equals("completed_at")) {
197                    this.completedAt = BoxDateFormat.parse(value.asString());
198                } else if (memberName.equals("assigned_at")) {
199                    this.assignedAt = BoxDateFormat.parse(value.asString());
200                } else if (memberName.equals("reminded_at")) {
201                    this.remindedAt = BoxDateFormat.parse(value.asString());
202                } else if (memberName.equals("resolution_state")) {
203                    this.resolutionState = ResolutionState.fromJSONString(value.asString());
204                } else if (memberName.equals("assigned_by")) {
205                    JsonObject userJSON = value.asObject();
206                    String userID = userJSON.get("id").asString();
207                    BoxUser user = new BoxUser(getAPI(), userID);
208                    this.assignedBy = user.new Info(userJSON);
209                }
210            } catch (ParseException e) {
211                assert false : "A ParseException indicates a bug in the SDK.";
212            }
213        }
214    }
215
216    /**
217     * Enumerates the possible resolution states that a task assignment can have.
218     */
219    public enum ResolutionState {
220        /**
221         * The task assignment has been completed.
222         */
223        COMPLETED ("completed"),
224
225        /**
226         * The task assignment is incomplete.
227         */
228        INCOMPLETE ("incomplete"),
229
230        /**
231         * The task assignment has been approved.
232         */
233        APPROVED ("approved"),
234
235        /**
236         * The task assignment has been rejected.
237         */
238        REJECTED ("rejected");
239
240        private final String jsonValue;
241
242        private ResolutionState(String jsonValue) {
243            this.jsonValue = jsonValue;
244        }
245
246        static ResolutionState fromJSONString(String jsonValue) {
247            if (jsonValue.equals("completed")) {
248                return COMPLETED;
249            } else if (jsonValue.equals("incomplete")) {
250                return INCOMPLETE;
251            } else if (jsonValue.equals("approved")) {
252                return APPROVED;
253            } else if (jsonValue.equals("rejected")) {
254                return REJECTED;
255            } else {
256                throw new IllegalArgumentException("The provided JSON value isn't a valid ResolutionState.");
257            }
258        }
259
260        String toJSONString() {
261            return this.jsonValue;
262        }
263    }
264}