001package com.box.sdk;
002
003import java.net.MalformedURLException;
004import java.net.URL;
005import java.util.Date;
006
007import com.eclipsesource.json.JsonArray;
008import com.eclipsesource.json.JsonObject;
009import com.eclipsesource.json.JsonValue;
010
011/**
012 * Represents an individual WebLink file on Box. This class can be used to retrieve the link's URL or perform other
013 * common file operations (move, copy, delete, etc.).
014 *
015 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
016 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
017 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
018 */
019@BoxResourceType("web_link")
020public class BoxWebLink extends BoxItem {
021
022    /**
023     * An array of all possible weblink fields that can be requested when calling {@link #getInfo()}.
024     */
025    public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "name", "url", "description",
026        "path_collection", "created_at", "modified_at", "trashed_at", "purged_at", "created_by", "modified_by",
027        "owned_by", "shared_link", "parent", "item_status", "collections"};
028
029    /**
030     * Copy URL Template.
031     */
032    public static final URLTemplate COPY_URL_TEMPLATE = new URLTemplate("web_links/%s/copy");
033    /**
034     * Web Link URL Template.
035     */
036    public static final URLTemplate WEB_LINK_URL_TEMPLATE = new URLTemplate("web_links/%s");
037
038    /**
039     * Constructs a BoxWebLink for a weblink with a given ID.
040     * @param  api the API connection to be used by the weblink.
041     * @param  id  the ID of the weblink.
042     */
043    public BoxWebLink(BoxAPIConnection api, String id) {
044        super(api, id);
045    }
046
047    @Override
048    public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
049        BoxSharedLink.Permissions permissions) {
050
051        BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions);
052        Info info = new Info();
053        info.setSharedLink(sharedLink);
054
055        this.updateInfo(info);
056        return info.getSharedLink();
057    }
058
059    @Override
060    public BoxWebLink.Info copy(BoxFolder destination) {
061        return this.copy(destination, null);
062    }
063
064    @Override
065    public BoxWebLink.Info copy(BoxFolder destination, String newName) {
066        URL url = COPY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
067
068        JsonObject parent = new JsonObject();
069        parent.add("id", destination.getID());
070
071        JsonObject copyInfo = new JsonObject();
072        copyInfo.add("parent", parent);
073        if (newName != null) {
074            copyInfo.add("name", newName);
075        }
076
077        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
078        request.setBody(copyInfo.toString());
079        BoxJSONResponse response = (BoxJSONResponse) request.send();
080        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
081        BoxWebLink copiedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString());
082        return copiedWebLink.new Info(responseJSON);
083    }
084
085    /**
086     * Deletes this weblink by moving it to the trash.
087     */
088    public void delete() {
089        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
090        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
091        BoxAPIResponse response = request.send();
092        response.disconnect();
093    }
094
095    @Override
096    public BoxItem.Info move(BoxFolder destination) {
097        return this.move(destination, null);
098    }
099
100    @Override
101    public BoxItem.Info move(BoxFolder destination, String newName) {
102        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
103        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
104
105        JsonObject parent = new JsonObject();
106        parent.add("id", destination.getID());
107
108        JsonObject updateInfo = new JsonObject();
109        updateInfo.add("parent", parent);
110        if (newName != null) {
111            updateInfo.add("name", newName);
112        }
113
114        request.setBody(updateInfo.toString());
115        BoxJSONResponse response = (BoxJSONResponse) request.send();
116        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
117        BoxWebLink movedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString());
118        return movedWebLink.new Info(responseJSON);
119    }
120
121    /**
122     * Renames this weblink.
123     * @param newName the new name of the weblink.
124     */
125    public void rename(String newName) {
126        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
127        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
128
129        JsonObject updateInfo = new JsonObject();
130        updateInfo.add("name", newName);
131
132        request.setBody(updateInfo.toString());
133        BoxAPIResponse response = request.send();
134        response.disconnect();
135    }
136
137    @Override
138    public BoxWebLink.Info getInfo() {
139        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
140        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
141        BoxJSONResponse response = (BoxJSONResponse) request.send();
142        return new Info(response.getJSON());
143    }
144
145    @Override
146    public BoxWebLink.Info getInfo(String... fields) {
147        String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
148        URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
149
150        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
151        BoxJSONResponse response = (BoxJSONResponse) request.send();
152        return new Info(response.getJSON());
153    }
154
155    /**
156     * Updates the information about this weblink with any info fields that have been modified locally.
157     *
158     * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following
159     * code won't update any information (or even send a network request) since none of the info's fields were
160     * changed:</p>
161     *
162     * <pre>BoxWebLink webLink = new BoxWebLink(api, id);
163     *BoxWebLink.Info info = webLink.getInfo();
164     *webLink.updateInfo(info);</pre>
165     *
166     * @param  info the updated info.
167     */
168    public void updateInfo(BoxWebLink.Info info) {
169        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
170        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
171        request.setBody(info.getPendingChanges());
172        String body = info.getPendingChanges();
173        BoxJSONResponse response = (BoxJSONResponse) request.send();
174        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
175        info.update(jsonObject);
176    }
177
178    @Override
179    public BoxWebLink.Info setCollections(BoxCollection... collections) {
180        JsonArray jsonArray = new JsonArray();
181        for (BoxCollection collection : collections) {
182            JsonObject collectionJSON = new JsonObject();
183            collectionJSON.add("id", collection.getID());
184            jsonArray.add(collectionJSON);
185        }
186        JsonObject infoJSON = new JsonObject();
187        infoJSON.add("collections", jsonArray);
188
189        String queryString = new QueryStringBuilder().appendParam("fields", ALL_FIELDS).toString();
190        URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
191        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
192        request.setBody(infoJSON.toString());
193        BoxJSONResponse response = (BoxJSONResponse) request.send();
194        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
195        return new Info(jsonObject);
196    }
197
198    /**
199     * Contains information about a BoxWebLink.
200     */
201    public class Info extends BoxItem.Info {
202        private URL linkURL;
203        private String description;
204
205        /**
206         * Constructs an empty Info object.
207         */
208        public Info() {
209            super();
210        }
211
212        /**
213         * Constructs an Info object by parsing information from a JSON string.
214         * @param  json the JSON string to parse.
215         */
216        public Info(String json) {
217            super(json);
218        }
219
220        /**
221         * Constructs an Info object using an already parsed JSON object.
222         * @param  jsonObject the parsed JSON object.
223         */
224        public Info(JsonObject jsonObject) {
225            super(jsonObject.toString());
226        }
227
228        @Override
229        public BoxWebLink getResource() {
230            return BoxWebLink.this;
231        }
232
233        /**
234         * Gets the description of this weblink.
235         * @return the description of this weblink.
236         */
237        public String getDescription() {
238            return this.description;
239        }
240
241        /**
242         * Gets the URL this weblink points to.
243         * @return the URL this weblink points to.
244         */
245        public URL getLinkURL() {
246            return this.linkURL;
247        }
248
249        @Override
250        protected void parseJSONMember(JsonObject.Member member) {
251            super.parseJSONMember(member);
252
253            String memberName = member.getName();
254            JsonValue value = member.getValue();
255            if (memberName.equals("url")) {
256                try {
257                    this.linkURL = new URL(value.asString());
258                } catch (MalformedURLException e) {
259                    throw new BoxAPIException("Couldn't parse url for weblink", e);
260                }
261            } else if (memberName.equals("description")) {
262                this.description = value.asString();
263            }
264        }
265    }
266}