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    private static final URLTemplate COPY_URL_TEMPLATE = new URLTemplate("web_links/%s/copy");
030    private static final URLTemplate WEB_LINK_URL_TEMPLATE = new URLTemplate("web_links/%s");
031
032    /**
033     * Constructs a BoxWebLink for a weblink with a given ID.
034     * @param  api the API connection to be used by the weblink.
035     * @param  id  the ID of the weblink.
036     */
037    public BoxWebLink(BoxAPIConnection api, String id) {
038        super(api, id);
039    }
040
041    @Override
042    public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate,
043        BoxSharedLink.Permissions permissions) {
044
045        BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions);
046        Info info = new Info();
047        info.setSharedLink(sharedLink);
048
049        this.updateInfo(info);
050        return info.getSharedLink();
051    }
052
053    @Override
054    public BoxWebLink.Info copy(BoxFolder destination) {
055        return this.copy(destination, null);
056    }
057
058    @Override
059    public BoxWebLink.Info copy(BoxFolder destination, String newName) {
060        URL url = COPY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
061
062        JsonObject parent = new JsonObject();
063        parent.add("id", destination.getID());
064
065        JsonObject copyInfo = new JsonObject();
066        copyInfo.add("parent", parent);
067        if (newName != null) {
068            copyInfo.add("name", newName);
069        }
070
071        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST");
072        request.setBody(copyInfo.toString());
073        BoxJSONResponse response = (BoxJSONResponse) request.send();
074        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
075        BoxWebLink copiedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString());
076        return copiedWebLink.new Info(responseJSON);
077    }
078
079    /**
080     * Deletes this weblink by moving it to the trash.
081     */
082    public void delete() {
083        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
084        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE");
085        BoxAPIResponse response = request.send();
086        response.disconnect();
087    }
088
089    @Override
090    public BoxItem.Info move(BoxFolder destination) {
091        return this.move(destination, null);
092    }
093
094    @Override
095    public BoxItem.Info move(BoxFolder destination, String newName) {
096        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
097        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
098
099        JsonObject parent = new JsonObject();
100        parent.add("id", destination.getID());
101
102        JsonObject updateInfo = new JsonObject();
103        updateInfo.add("parent", parent);
104        if (newName != null) {
105            updateInfo.add("name", newName);
106        }
107
108        request.setBody(updateInfo.toString());
109        BoxJSONResponse response = (BoxJSONResponse) request.send();
110        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
111        BoxWebLink movedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString());
112        return movedWebLink.new Info(responseJSON);
113    }
114
115    /**
116     * Renames this weblink.
117     * @param newName the new name of the weblink.
118     */
119    public void rename(String newName) {
120        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
121        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
122
123        JsonObject updateInfo = new JsonObject();
124        updateInfo.add("name", newName);
125
126        request.setBody(updateInfo.toString());
127        BoxAPIResponse response = request.send();
128        response.disconnect();
129    }
130
131    @Override
132    public BoxWebLink.Info getInfo() {
133        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
134        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
135        BoxJSONResponse response = (BoxJSONResponse) request.send();
136        return new Info(response.getJSON());
137    }
138
139    @Override
140    public BoxWebLink.Info getInfo(String... fields) {
141        String queryString = new QueryStringBuilder().appendParam("fields", fields).toString();
142        URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
143
144        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
145        BoxJSONResponse response = (BoxJSONResponse) request.send();
146        return new Info(response.getJSON());
147    }
148
149    /**
150     * Updates the information about this weblink with any info fields that have been modified locally.
151     *
152     * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following
153     * code won't update any information (or even send a network request) since none of the info's fields were
154     * changed:</p>
155     *
156     * <pre>BoxWebLink webLink = new BoxWebLink(api, id);
157     *BoxWebLink.Info info = webLink.getInfo();
158     *webLink.updateInfo(info);</pre>
159     *
160     * @param  info the updated info.
161     */
162    public void updateInfo(BoxWebLink.Info info) {
163        URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID());
164        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
165        request.setBody(info.getPendingChanges());
166        String body = info.getPendingChanges();
167        BoxJSONResponse response = (BoxJSONResponse) request.send();
168        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
169        info.update(jsonObject);
170    }
171
172    @Override
173    public BoxWebLink.Info setCollections(BoxCollection... collections) {
174        JsonArray jsonArray = new JsonArray();
175        for (BoxCollection collection : collections) {
176            JsonObject collectionJSON = new JsonObject();
177            collectionJSON.add("id", collection.getID());
178            jsonArray.add(collectionJSON);
179        }
180        JsonObject infoJSON = new JsonObject();
181        infoJSON.add("collections", jsonArray);
182
183        String queryString = new QueryStringBuilder().appendParam("fields", ALL_FIELDS).toString();
184        URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID());
185        BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT");
186        request.setBody(infoJSON.toString());
187        BoxJSONResponse response = (BoxJSONResponse) request.send();
188        JsonObject jsonObject = JsonObject.readFrom(response.getJSON());
189        return new Info(jsonObject);
190    }
191
192    /**
193     * Contains information about a BoxWebLink.
194     */
195    public class Info extends BoxItem.Info {
196        private URL linkURL;
197        private String description;
198
199        /**
200         * Constructs an empty Info object.
201         */
202        public Info() {
203            super();
204        }
205
206        /**
207         * Constructs an Info object by parsing information from a JSON string.
208         * @param  json the JSON string to parse.
209         */
210        public Info(String json) {
211            super(json);
212        }
213
214        /**
215         * Constructs an Info object using an already parsed JSON object.
216         * @param  jsonObject the parsed JSON object.
217         */
218        public Info(JsonObject jsonObject) {
219            super(jsonObject.toString());
220        }
221
222        @Override
223        public BoxWebLink getResource() {
224            return BoxWebLink.this;
225        }
226
227        /**
228         * Gets the description of this weblink.
229         * @return the description of this weblink.
230         */
231        public String getDescription() {
232            return this.description;
233        }
234
235        /**
236         * Gets the URL this weblink points to.
237         * @return the URL this weblink points to.
238         */
239        public URL getLinkURL() {
240            return this.linkURL;
241        }
242
243        @Override
244        protected void parseJSONMember(JsonObject.Member member) {
245            super.parseJSONMember(member);
246
247            String memberName = member.getName();
248            JsonValue value = member.getValue();
249            if (memberName.equals("url")) {
250                try {
251                    this.linkURL = new URL(value.asString());
252                } catch (MalformedURLException e) {
253                    throw new BoxAPIException("Couldn't parse url for weblink", e);
254                }
255            } else if (memberName.equals("description")) {
256                this.description = value.asString();
257            }
258        }
259    }
260}