001package com.box.sdk;
002
003import static com.box.sdk.BinaryBodyUtils.writeStream;
004
005import com.eclipsesource.json.Json;
006import com.eclipsesource.json.JsonObject;
007import com.eclipsesource.json.JsonValue;
008import java.io.OutputStream;
009import java.net.URL;
010import java.text.ParseException;
011import java.util.Date;
012
013/**
014 * Represents a particular version of a file on Box.
015 */
016@BoxResourceType("file_version")
017public class BoxFileVersion extends BoxResource {
018    /**
019     * Content URL Template.
020     */
021    public static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content?version=%s");
022    /**
023     * Version URL Template.
024     */
025    public static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s");
026
027    /**
028     * The default limit of entries per response.
029     */
030    public static final long DEFAULT_LIMIT = 1000;
031
032    private String fileID;
033
034    private String versionID;
035    private String sha1;
036    private String name;
037    private long size;
038    private String uploaderDisplayName;
039    private Date createdAt;
040    private Date modifiedAt;
041    private BoxUser.Info modifiedBy;
042    private Date trashedAt;
043    private BoxUser.Info trashedBy;
044    private Date restoredAt;
045    private BoxUser.Info restoredBy;
046    private Date purgedAt;
047    private Long versionNumber;
048
049    /**
050     * Constructs a BoxFileVersion from a JSON string.
051     *
052     * @param api    the API connection to be used by the file.
053     * @param json   the JSON encoded file version.
054     * @param fileID the ID of the file.
055     */
056    public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
057        this(api, Json.parse(json).asObject(), fileID);
058    }
059
060    BoxFileVersion(BoxAPIConnection api, JsonObject jsonObject, String fileID) {
061        super(api, jsonObject.get("id").asString());
062
063        this.fileID = fileID;
064        this.parseJSON(jsonObject);
065    }
066
067    /**
068     * Method used to update fields with values received from API.
069     *
070     * @param jsonObject JSON-encoded info about File Version object.
071     */
072    private void parseJSON(JsonObject jsonObject) {
073        for (JsonObject.Member member : jsonObject) {
074            JsonValue value = member.getValue();
075            if (value.isNull()) {
076                continue;
077            }
078
079            try {
080                String memberName = member.getName();
081                if (memberName.equals("id")) {
082                    this.versionID = value.asString();
083                } else if (memberName.equals("sha1")) {
084                    this.sha1 = value.asString();
085                } else if (memberName.equals("name")) {
086                    this.name = value.asString();
087                } else if (memberName.equals("size")) {
088                    this.size = Double.valueOf(value.toString()).longValue();
089                } else if (memberName.equals("uploader_display_name")) {
090                    this.uploaderDisplayName = value.asString();
091                } else if (memberName.equals("created_at")) {
092                    this.createdAt = BoxDateFormat.parse(value.asString());
093                } else if (memberName.equals("modified_at")) {
094                    this.modifiedAt = BoxDateFormat.parse(value.asString());
095                } else if (memberName.equals("trashed_at")) {
096                    this.trashedAt = BoxDateFormat.parse(value.asString());
097                } else if (memberName.equals("trashed_by")) {
098                    JsonObject userJSON = value.asObject();
099                    String userID = userJSON.get("id").asString();
100                    BoxUser user = new BoxUser(getAPI(), userID);
101                    this.trashedBy = user.new Info(userJSON);
102                } else if (memberName.equals("modified_by")) {
103                    JsonObject userJSON = value.asObject();
104                    String userID = userJSON.get("id").asString();
105                    BoxUser user = new BoxUser(getAPI(), userID);
106                    this.modifiedBy = user.new Info(userJSON);
107                } else if (memberName.equals("restored_at")) {
108                    this.restoredAt = BoxDateFormat.parse(value.asString());
109                } else if (memberName.equals("restored_by")) {
110                    JsonObject userJSON = value.asObject();
111                    String userID = userJSON.get("id").asString();
112                    BoxUser user = new BoxUser(getAPI(), userID);
113                    this.restoredBy = user.new Info(userJSON);
114                } else if (memberName.equals("purged_at")) {
115                    this.purgedAt = BoxDateFormat.parse(value.asString());
116                } else if (memberName.equals("version_number")) {
117                    this.versionNumber = Long.parseLong(value.asString());
118                }
119            } catch (ParseException e) {
120                assert false : "A ParseException indicates a bug in the SDK.";
121            }
122        }
123    }
124
125    /**
126     * @return the file id this file version belongs to.
127     */
128    public String getFileID() {
129        return this.fileID;
130    }
131
132    /**
133     * Used if no or wrong file id was set with constructor.
134     *
135     * @param fileID the file id this file version belongs to.
136     */
137    public void setFileID(String fileID) {
138        this.fileID = fileID;
139    }
140
141    /**
142     * Gets the version ID of this version of the file.
143     *
144     * @return the version ID of this version of the file.
145     */
146    public String getVersionID() {
147        return this.versionID;
148    }
149
150    /**
151     * Gets the SHA1 hash of this version of the file.
152     *
153     * @return the SHA1 hash of this version of the file.
154     */
155    public String getSha1() {
156        return this.sha1;
157    }
158
159    /**
160     * Gets the name of this version of the file.
161     *
162     * @return the name of this version of the file.
163     */
164    public String getName() {
165        return this.name;
166    }
167
168    /**
169     * Gets the size of this version of the file.
170     *
171     * @return the size of this version of the file.
172     */
173    public long getSize() {
174        return this.size;
175    }
176
177    /**
178     * Gets the time that this version of the file was created.
179     *
180     * @return the time that this version of the file was created.
181     */
182    public Date getCreatedAt() {
183        return this.createdAt;
184    }
185
186    /**
187     * Gets the user's name at the time of upload.
188     *
189     * @return the time user's name at the time of upload.
190     */
191    public String getUploaderDisplayName() {
192        return this.uploaderDisplayName;
193    }
194
195    /**
196     * Gets the time that this version of the file was modified.
197     *
198     * @return the time that this version of the file was modified.
199     */
200    public Date getModifiedAt() {
201        return this.modifiedAt;
202    }
203
204    /**
205     * Gets the time that this version of the file was deleted.
206     *
207     * @return the time that this version of the file was deleted.
208     */
209    public Date getTrashedAt() {
210        return this.trashedAt;
211    }
212
213    /**
214     * Gets information about the user who trashed this version of the file.
215     *
216     * @return info about the user who trashed this version of the file.
217     */
218    public BoxUser.Info getTrashedBy() {
219        return this.trashedBy;
220    }
221
222    /**
223     * Gets information about the user who last modified this version of the file.
224     *
225     * @return info about the user who last modified this version of the file.
226     */
227    public BoxUser.Info getModifiedBy() {
228        return this.modifiedBy;
229    }
230
231    /**
232     * Gets the time that this version of the file was restored.
233     *
234     * @return the time that this version of the file was restored.
235     */
236    public Date getRestoredAt() {
237        return this.restoredAt;
238    }
239
240    /**
241     * Gets information about the user who restored this version of the file.
242     *
243     * @return info about the user who restored this version of the file.
244     */
245    public BoxUser.Info getRestoredBy() {
246        return this.restoredBy;
247    }
248
249    /**
250     * Gets the time that this version of the file was purged.
251     *
252     * @return the time that this version of the file was purged.
253     */
254    public Date getPurgedAt() {
255        return this.purgedAt;
256    }
257
258    /**
259     * Returns version number.
260     *
261     * @return version number
262     */
263    public Long getVersionNumber() {
264        return versionNumber;
265    }
266
267    /**
268     * Deletes this version of the file.
269     */
270    public void delete() {
271        URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
272        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
273        request.send().close();
274    }
275
276    /**
277     * Downloads this version of the file to a given OutputStream.
278     *
279     * @param output the stream to where the file will be written.
280     */
281    public void download(OutputStream output) {
282        this.download(output, null);
283    }
284
285    /**
286     * Downloads this version of the file to a given OutputStream while reporting the progress to a ProgressListener.
287     *
288     * @param output   the stream to where the file will be written.
289     * @param listener a listener for monitoring the download's progress.
290     */
291    public void download(OutputStream output, ProgressListener listener) {
292        URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
293        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
294        writeStream(request.send(), output, listener);
295    }
296
297    /**
298     * Promotes this version of the file to be the latest version.
299     */
300    public void promote() {
301        URL url = VERSION_URL_TEMPLATE.buildAlpha(this.getAPI().getBaseURL(), this.fileID, "current");
302
303        JsonObject jsonObject = new JsonObject();
304        jsonObject.add("type", "file_version");
305        jsonObject.add("id", this.getID());
306
307        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
308        request.setBody(jsonObject.toString());
309        try (BoxJSONResponse response = request.send()) {
310            this.parseJSON(Json.parse(response.getJSON()).asObject());
311        }
312    }
313}