001package com.box.sdk;
002
003import java.io.IOException;
004import java.io.InputStream;
005import java.io.OutputStream;
006import java.net.URL;
007import java.text.ParseException;
008import java.util.Date;
009
010import com.eclipsesource.json.JsonObject;
011import com.eclipsesource.json.JsonValue;
012
013/**
014 * Represents a particular version of a file on Box.
015 */
016public class BoxFileVersion extends BoxResource {
017    private static final URLTemplate CONTENT_URL_TEMPLATE = new URLTemplate("files/%s/content?version=%s");
018    private static final URLTemplate VERSION_URL_TEMPLATE = new URLTemplate("files/%s/versions/%s");
019    private static final int BUFFER_SIZE = 8192;
020
021    private final String fileID;
022
023    private String sha1;
024    private String name;
025    private long size;
026    private Date createdAt;
027    private Date modifiedAt;
028    private BoxUser.Info modifiedBy;
029
030    /**
031     * Constructs a BoxFileVersion from a JSON string.
032     * @param  api    the API connection to be used by the file.
033     * @param  json   the JSON encoded file version.
034     * @param  fileID the ID of the file.
035     */
036    public BoxFileVersion(BoxAPIConnection api, String json, String fileID) {
037        this(api, JsonObject.readFrom(json), fileID);
038    }
039
040    BoxFileVersion(BoxAPIConnection api, JsonObject jsonObject, String fileID) {
041        super(api, jsonObject.get("id").asString());
042
043        this.fileID = fileID;
044        for (JsonObject.Member member : jsonObject) {
045            JsonValue value = member.getValue();
046            if (value.isNull()) {
047                continue;
048            }
049
050            try {
051                String memberName = member.getName();
052                if (memberName.equals("sha1")) {
053                    this.sha1 = value.asString();
054                } else if (memberName.equals("name")) {
055                    this.name = value.asString();
056                } else if (memberName.equals("size")) {
057                    this.size = Double.valueOf(value.toString()).longValue();
058                } else if (memberName.equals("created_at")) {
059                    this.createdAt = BoxDateFormat.parse(value.asString());
060                } else if (memberName.equals("modified_at")) {
061                    this.modifiedAt = BoxDateFormat.parse(value.asString());
062                } else if (memberName.equals("modified_by")) {
063                    JsonObject userJSON = value.asObject();
064                    String userID = userJSON.get("id").asString();
065                    BoxUser user = new BoxUser(getAPI(), userID);
066                    this.modifiedBy = user.new Info(userJSON);
067                }
068            } catch (ParseException e) {
069                assert false : "A ParseException indicates a bug in the SDK.";
070            }
071        }
072    }
073
074    /**
075     * Gets the SHA1 hash of this version of the file.
076     * @return the SHA1 hash of this version of the file.
077     */
078    public String getSha1() {
079        return this.sha1;
080    }
081
082    /**
083     * Gets the name of this version of the file.
084     * @return the name of this version of the file.
085     */
086    public String getName() {
087        return this.name;
088    }
089
090    /**
091     * Gets the size of this version of the file.
092     * @return the size of this version of the file.
093     */
094    public long getSize() {
095        return this.size;
096    }
097
098    /**
099     * Gets the time that this version of the file was created.
100     * @return the time that this version of the file was created.
101     */
102    public Date getCreatedAt() {
103        return this.createdAt;
104    }
105
106    /**
107     * Gets the time that this version of the file was modified.
108     * @return the time that this version of the file was modified.
109     */
110    public Date getModifiedAt() {
111        return this.modifiedAt;
112    }
113
114    /**
115     * Gets information about the user who last modified this version of the file.
116     * @return info about the user who last modified this version of the file.
117     */
118    public BoxUser.Info getModifiedBy() {
119        return this.modifiedBy;
120    }
121
122    /**
123     * Deletes this version of the file.
124     */
125    public void delete() {
126        URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
127        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
128        BoxAPIResponse response = request.send();
129        response.disconnect();
130    }
131
132    /**
133     * Downloads this version of the file to a given OutputStream.
134     * @param output the stream to where the file will be written.
135     */
136    public void download(OutputStream output) {
137        this.download(output, null);
138    }
139
140    /**
141     * Downloads this version of the file to a given OutputStream while reporting the progress to a ProgressListener.
142     * @param output   the stream to where the file will be written.
143     * @param listener a listener for monitoring the download's progress.
144     */
145    public void download(OutputStream output, ProgressListener listener) {
146        URL url = CONTENT_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, this.getID());
147        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
148        BoxAPIResponse response = request.send();
149        InputStream input = response.getBody(listener);
150
151        long totalRead = 0;
152        byte[] buffer = new byte[BUFFER_SIZE];
153        try {
154            int n = input.read(buffer);
155            totalRead += n;
156            while (n != -1) {
157                output.write(buffer, 0, n);
158                n = input.read(buffer);
159                totalRead += n;
160            }
161        } catch (IOException e) {
162            throw new BoxAPIException("Couldn't connect to the Box API due to a network error.", e);
163        }
164
165        response.disconnect();
166    }
167
168    /**
169     * Promotes this version of the file to be the latest version.
170     */
171    public void promote() {
172        URL url = VERSION_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.fileID, "current");
173
174        JsonObject jsonObject = new JsonObject();
175        jsonObject.add("type", "file_version");
176        jsonObject.add("id", this.getID());
177
178        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
179        request.setBody(jsonObject.toString());
180        BoxAPIResponse response = request.send();
181        response.disconnect();
182    }
183}