001package com.box.sdk;
002
003import java.net.MalformedURLException;
004import java.net.URL;
005import java.util.Date;
006
007import com.eclipsesource.json.JsonObject;
008import com.eclipsesource.json.JsonValue;
009
010/**
011 * Represents a file request on Box.
012 */
013@BoxResourceType("file_request")
014public class BoxFileRequest extends BoxResource {
015
016    /**
017     * File Request URL Template.
018     */
019    public static final URLTemplate FILE_REQUEST_URL_TEMPLATE = new URLTemplate("file_requests/%s");
020    /**
021     * Copy File Request URL Template.
022     */
023    public static final URLTemplate COPY_FILE_REQUEST_URL_TEMPLATE = new URLTemplate("file_requests/%s/copy");
024
025    /**
026     * Constructs a BoxFileRequest for a file request with a given ID.
027     *
028     * @param api the API connection to be used by the file request.
029     * @param id  the ID of the file request.
030     */
031    public BoxFileRequest(BoxAPIConnection api, String id) {
032        super(api, id);
033    }
034
035    /**
036     * Gets information about this file request.
037     *
038     * @return info about this file request.
039     */
040    public BoxFileRequest.Info getInfo() {
041        URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
042        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
043        BoxJSONResponse response = (BoxJSONResponse) request.send();
044        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
045        return new Info(responseJSON);
046    }
047
048    /**
049     * Copies this file request that is already present on one folder, and applies it to another folder.
050     *
051     * @param folderId the ID of the folder for the file request.
052     * @return info about the newly copied file request.
053     */
054    public BoxFileRequest.Info copyInfo(String folderId) {
055        URL url = COPY_FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
056        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
057        JsonObject body = new JsonObject();
058        JsonObject folderBody = new JsonObject();
059        folderBody.add("id", folderId);
060        folderBody.add("type", "folder");
061        body.add("folder", folderBody);
062        request.setBody(body.toString());
063        BoxJSONResponse response = (BoxJSONResponse) request.send();
064        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
065        return new Info(jsonObject);
066    }
067
068    /**
069     * Copies this file request that is already present on one folder, and applies it to another folder.
070     *
071     * <p>Info fields that have been modified locally will overwrite the values in the original file request.
072     *
073     * @param info     the info.
074     * @param folderId the ID of the folder for the file request.
075     * @return info about the newly copied file request.
076     */
077    public BoxFileRequest.Info copyInfo(BoxFileRequest.Info info, String folderId) {
078        URL url = COPY_FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
079        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
080        JsonObject body = new JsonObject();
081        JsonObject pendingChanges = info.getPendingChangesAsJsonObject();
082        if (pendingChanges != null) {
083            body = pendingChanges;
084        }
085        JsonObject folderBody = new JsonObject();
086        folderBody.add("id", folderId);
087        folderBody.add("type", "folder");
088        body.add("folder", folderBody);
089        request.setBody(body.toString());
090        BoxJSONResponse response = (BoxJSONResponse) request.send();
091        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
092        info.update(jsonObject);
093        return new Info(jsonObject);
094    }
095
096    /**
097     * Updates the information about this file request with any info fields that have been modified locally.
098     *
099     * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following
100     * code won't update any information (or even send a network request) since none of the info's fields were
101     * changed:</p>
102     *
103     * <pre>BoxFileRequest fileRequest = new BoxFileRequest(api, id);
104     * BoxFileRequest.Info info = fileRequest.getInfo();
105     * info.updateInfo(info);</pre>
106     *
107     * @param info the updated info.
108     * @return info about the updated file request.
109     */
110    public BoxFileRequest.Info updateInfo(BoxFileRequest.Info info) {
111        URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
112        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
113        request.setBody(info.getPendingChanges());
114        BoxJSONResponse response = (BoxJSONResponse) request.send();
115        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
116        info.update(jsonObject);
117        return info;
118    }
119
120    /**
121     * Delete this file request.
122     */
123    public void delete() {
124        URL url = FILE_REQUEST_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
125        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
126        BoxAPIResponse response = request.send();
127        response.disconnect();
128    }
129
130    /**
131     * Contains information about a BoxFileRequest.
132     */
133    public class Info extends BoxResource.Info {
134        private String type;
135        private Date createdAt;
136        private BoxUser.Info createdBy;
137        private String description;
138        private String etag;
139        private Date expiresAt;
140        private BoxFolder.Info folder;
141        private boolean isDescriptionRequired;
142        private boolean isEmailRequired;
143        private Status status;
144        private String title;
145        private Date updatedAt;
146        private BoxUser.Info updatedBy;
147        private URL url;
148
149        /**
150         * Constructs an empty Info object.
151         */
152        public Info() {
153            super();
154        }
155
156        /**
157         * Constructs an Info object by parsing information from a JSON string.
158         *
159         * @param json the JSON string to parse.
160         */
161        public Info(String json) {
162            super(json);
163        }
164
165        /**
166         * Constructs an Info object using an already parsed JSON object.
167         *
168         * @param jsonObject the parsed JSON object.
169         */
170        Info(JsonObject jsonObject) {
171            super(jsonObject);
172        }
173
174        @Override
175        public BoxFileRequest getResource() {
176            return BoxFileRequest.this;
177        }
178
179        /**
180         * Gets the file request type.
181         *
182         * @return the file request type.
183         */
184        public String getType() {
185            return this.type;
186        }
187
188        /**
189         * Gets the date when the file request was created.
190         *
191         * @return the date when the file request was created.
192         */
193        public Date getCreatedAt() {
194            return this.createdAt;
195        }
196
197        /**
198         * Gets the user who created this file request.
199         *
200         * @return the user who created this file request.
201         */
202        public BoxUser.Info getCreatedBy() {
203            return this.createdBy;
204        }
205
206        /**
207         * Gets the description of this file request.
208         *
209         * @return the description of this file request.
210         */
211        public String getDescription() {
212            return this.description;
213        }
214
215        /**
216         * Sets the description of this file request.
217         *
218         * @param description the file request's new description.
219         */
220        public void setDescription(String description) {
221            this.description = description;
222            this.addPendingChange("description", description);
223        }
224
225        /**
226         * Gets a unique string identifying the version of the item.
227         *
228         * @return a unique string identifying the version of the item.
229         */
230        public String getEtag() {
231            return this.etag;
232        }
233
234        /**
235         * Gets the date after which a file request will no longer accept new submissions.
236         *
237         * @return the date after which a file request will no longer accept new submissions.
238         */
239        public Date getExpiresAt() {
240            return this.expiresAt;
241        }
242
243
244        /**
245         * Sets the date after which a file request will no longer accept new submissions.
246         *
247         * @param expiresAt the date after which a file request will no longer accept new submissions.
248         */
249        public void setExpiresAt(Date expiresAt) {
250            this.expiresAt = expiresAt;
251            this.addPendingChange("expires_at", BoxDateFormat.format(expiresAt));
252        }
253
254        /**
255         * Gets the folder that this file request is associated with.
256         *
257         * @return the folder that this file request is associated with.
258         */
259        public BoxFolder.Info getFolder() {
260            return this.folder;
261        }
262
263        /**
264         * Gets whether a file request submitter is required to provide a description of the files they are submitting.
265         *
266         * @return whether a file request submitter is required to provide a description of the files they
267         * are submitting.
268         */
269        public Boolean getIsDescriptionRequired() {
270            return this.isDescriptionRequired;
271        }
272
273        /**
274         * Sets whether a file request submitter is required to provide a description of the files they are submitting.
275         *
276         * @param isDescriptionRequired whether a file request submitter is required to provide a description of the
277         *                              files they are submitting.
278         */
279        public void setIsDescriptionRequired(Boolean isDescriptionRequired) {
280            this.isDescriptionRequired = isDescriptionRequired;
281            this.addPendingChange("is_description_required", isDescriptionRequired);
282        }
283
284        /**
285         * Gets whether a file request submitter is required to provide their email address.
286         *
287         * @return whether a file request submitter is required to provide their email address.
288         */
289        public Boolean getIsEmailRequired() {
290            return this.isEmailRequired;
291        }
292
293        /**
294         * Sets whether a file request submitter is required to provide their email address.
295         *
296         * @param isEmailRequired whether a file request submitter is required to provide their email address.
297         */
298        public void setIsEmailRequired(Boolean isEmailRequired) {
299            this.isEmailRequired = isEmailRequired;
300            this.addPendingChange("is_email_required", isEmailRequired);
301        }
302
303        /**
304         * Gets the status of the file request.
305         *
306         * @return the status of the file request
307         */
308        public Status getStatus() {
309            return this.status;
310        }
311
312
313        /**
314         * Sets the status of the file request.
315         *
316         * @param status the status of the file request
317         */
318        public void setStatus(Status status) {
319            this.status = status;
320            this.addPendingChange("status", status.toJSONString());
321        }
322
323        /**
324         * Gets the title of file request.
325         *
326         * @return the title of file request.
327         */
328        public String getTitle() {
329            return this.title;
330        }
331
332        /**
333         * Sets the title of file request.
334         *
335         * @param title the title of file request.
336         */
337        public void setTitle(String title) {
338            this.title = title;
339            this.addPendingChange("title", title);
340        }
341
342        /**
343         * Gets the date when the file request was last updated.
344         *
345         * @return the date when the file request was last updated.
346         */
347        public Date getUpdatedAt() {
348            return this.updatedAt;
349        }
350
351        /**
352         * Gets the user who last modified this file request.
353         *
354         * @return the user who last modified this file request.
355         */
356        public BoxUser.Info getUpdatedBy() {
357            return this.updatedBy;
358        }
359
360        /**
361         * Gets the URL can be shared with users to let them upload files to the associated folder.
362         *
363         * @return the date at which this task is due.
364         */
365        public URL getUrl() {
366            return this.url;
367        }
368
369        @Override
370        void parseJSONMember(JsonObject.Member member) {
371            super.parseJSONMember(member);
372
373            String memberName = member.getName();
374            JsonValue value = member.getValue();
375            try {
376                if (memberName.equals("type")) {
377                    this.type = value.asString();
378                } else if (memberName.equals("created_at")) {
379                    this.createdAt = BoxDateFormat.parse(value.asString());
380                } else if (memberName.equals("created_by")) {
381                    JsonObject userJSON = value.asObject();
382                    String userID = userJSON.get("id").asString();
383                    BoxUser user = new BoxUser(getAPI(), userID);
384                    this.createdBy = user.new Info(userJSON);
385                } else if (memberName.equals("description")) {
386                    this.description = value.asString();
387                } else if (memberName.equals("etag")) {
388                    this.etag = value.asString();
389                } else if (memberName.equals("expires_at")) {
390                    this.expiresAt = BoxDateFormat.parse(value.asString());
391                } else if (memberName.equals("folder")) {
392                    JsonObject folderJSON = value.asObject();
393                    String folderID = folderJSON.get("id").asString();
394                    BoxFolder folder = new BoxFolder(getAPI(), folderID);
395                    this.folder = folder.new Info(folderJSON);
396                } else if (memberName.equals("is_description_required")) {
397                    this.isDescriptionRequired = value.asBoolean();
398                } else if (memberName.equals("is_email_required")) {
399                    this.isEmailRequired = value.asBoolean();
400                } else if (memberName.equals("status")) {
401                    this.status = Status.fromJSONString(value.asString());
402                } else if (memberName.equals("title")) {
403                    this.title = value.asString();
404                } else if (memberName.equals("updated_at")) {
405                    this.updatedAt = BoxDateFormat.parse(value.asString());
406                } else if (memberName.equals("updated_by")) {
407                    JsonObject userJSON = value.asObject();
408                    String userID = userJSON.get("id").asString();
409                    BoxUser user = new BoxUser(getAPI(), userID);
410                    this.createdBy = user.new Info(userJSON);
411                } else if (memberName.equals("url")) {
412                    try {
413                        String urlString = value.asString();
414                        this.url = new URL(urlString);
415                    } catch (MalformedURLException e) {
416                        throw new BoxAPIException("Couldn't parse url for file request", e);
417                    }
418                }
419            } catch (Exception e) {
420                throw new BoxDeserializationException(memberName, value.toString(), e);
421            }
422        }
423    }
424
425    /**
426     * The status of the file request.
427     */
428    public enum Status {
429        /**
430         * The file request can accept new submissions.
431         */
432        ACTIVE("active"),
433
434        /**
435         * The file request can't accept new submissions.
436         */
437        INACTIVE("inactive");
438
439        private final String jsonValue;
440
441        private Status(String jsonValue) {
442            this.jsonValue = jsonValue;
443        }
444
445        static Status fromJSONString(String jsonValue) {
446            return Status.valueOf(jsonValue.toUpperCase());
447        }
448
449        String toJSONString() {
450            return this.jsonValue;
451        }
452    }
453}