001package com.box.sdk; 002 003import com.box.sdk.sharedlink.BoxSharedLinkWithoutPermissionsRequest; 004import com.eclipsesource.json.Json; 005import com.eclipsesource.json.JsonArray; 006import com.eclipsesource.json.JsonObject; 007import com.eclipsesource.json.JsonValue; 008import java.net.MalformedURLException; 009import java.net.URL; 010import java.util.Date; 011 012/** 013 * Represents an individual WebLink file on Box. This class can be used to retrieve the link's URL or perform other 014 * common file operations (move, copy, delete, etc.). 015 * 016 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked 017 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error 018 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p> 019 */ 020@BoxResourceType("web_link") 021public class BoxWebLink extends BoxItem { 022 023 /** 024 * An array of all possible weblink fields that can be requested when calling {@link #getInfo()}. 025 */ 026 public static final String[] ALL_FIELDS = {"type", "id", "sequence_id", "etag", "name", "url", "description", 027 "path_collection", "created_at", "modified_at", "trashed_at", "purged_at", "created_by", "modified_by", 028 "owned_by", "shared_link", "parent", "item_status", "collections"}; 029 030 /** 031 * Copy URL Template. 032 */ 033 public static final URLTemplate COPY_URL_TEMPLATE = new URLTemplate("web_links/%s/copy"); 034 /** 035 * Web Link URL Template. 036 */ 037 public static final URLTemplate WEB_LINK_URL_TEMPLATE = new URLTemplate("web_links/%s"); 038 039 /** 040 * Constructs a BoxWebLink for a weblink with a given ID. 041 * 042 * @param api the API connection to be used by the weblink. 043 * @param id the ID of the weblink. 044 */ 045 public BoxWebLink(BoxAPIConnection api, String id) { 046 super(api, id); 047 } 048 049 /** 050 * Creates a new shared link for this item. 051 * 052 * <p>This method is a convenience method for manually creating a new shared link and applying it to this item with 053 * {@link BoxItem.Info#setSharedLink}. You may want to create the shared link manually so that it can be updated along with 054 * other changes to the item's info in a single network request, giving a boost to performance.</p> 055 * 056 * @param access the access level of the shared link. 057 * @param unshareDate the date and time at which the link will expire. Can be null to create a non-expiring link. 058 * @param permissions the permissions of the shared link. Can be null to use the default permissions. 059 * @return the created shared link. 060 * @deprecated use {@link BoxWebLink#createSharedLink(BoxSharedLinkWithoutPermissionsRequest)} 061 */ 062 @Override 063 @Deprecated 064 public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate, 065 BoxSharedLink.Permissions permissions) { 066 067 if (permissions != null) { 068 throw new IllegalArgumentException( 069 "Cannot set permissions on a shared link to web link. " 070 + "The BoxWebLink#createSharedLink(BoxSharedLinkWithoutPermissionsRequest) is preferred." 071 ); 072 } 073 BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions); 074 return this.createSharedLink(sharedLink); 075 } 076 077 /** 078 * Creates new SharedLink for a BoxWebLink with a password. 079 * 080 * @param access The access level of the shared link. 081 * @param unshareDate A specified date to unshare the Box web link. 082 * @param permissions The permissions to set on the shared link for the Box web link. 083 * @param password Password set on the shared link to give access to the Box web link. 084 * @return information about the newly created shared link. 085 * @deprecated Use {@link BoxWebLink#createSharedLink(BoxSharedLinkWithoutPermissionsRequest)} 086 */ 087 @Deprecated 088 public BoxSharedLink createSharedLink(BoxSharedLink.Access access, Date unshareDate, 089 BoxSharedLink.Permissions permissions, String password) { 090 091 if (permissions != null) { 092 throw new IllegalArgumentException( 093 "Cannot set permissions on a shared link to web link. " 094 + "The BoxWebLink#createSharedLink(BoxSharedLinkWithoutPermissionsRequest) is supported." 095 ); 096 } 097 BoxSharedLink sharedLink = new BoxSharedLink(access, unshareDate, permissions, password); 098 return this.createSharedLink(sharedLink); 099 } 100 101 /** 102 * Creates a shared link. 103 * 104 * @param sharedLinkRequest Shared link to create 105 * @return Created shared link. 106 */ 107 public BoxSharedLink createSharedLink(BoxSharedLinkWithoutPermissionsRequest sharedLinkRequest) { 108 return createSharedLink(sharedLinkRequest.asSharedLink()); 109 } 110 111 private BoxSharedLink createSharedLink(BoxSharedLink sharedLink) { 112 BoxWebLink.Info info = new BoxWebLink.Info(); 113 info.setSharedLink(sharedLink); 114 115 this.updateInfo(info); 116 return info.getSharedLink(); 117 } 118 119 120 @Override 121 public BoxWebLink.Info copy(BoxFolder destination) { 122 return this.copy(destination, null); 123 } 124 125 @Override 126 public BoxWebLink.Info copy(BoxFolder destination, String newName) { 127 URL url = COPY_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 128 129 JsonObject parent = new JsonObject(); 130 parent.add("id", destination.getID()); 131 132 JsonObject copyInfo = new JsonObject(); 133 copyInfo.add("parent", parent); 134 if (newName != null) { 135 copyInfo.add("name", newName); 136 } 137 138 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "POST"); 139 request.setBody(copyInfo.toString()); 140 BoxJSONResponse response = (BoxJSONResponse) request.send(); 141 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 142 BoxWebLink copiedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString()); 143 return copiedWebLink.new Info(responseJSON); 144 } 145 146 /** 147 * Deletes this weblink by moving it to the trash. 148 */ 149 public void delete() { 150 URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 151 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "DELETE"); 152 BoxAPIResponse response = request.send(); 153 response.disconnect(); 154 } 155 156 @Override 157 public BoxItem.Info move(BoxFolder destination) { 158 return this.move(destination, null); 159 } 160 161 @Override 162 public BoxItem.Info move(BoxFolder destination, String newName) { 163 URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 164 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 165 166 JsonObject parent = new JsonObject(); 167 parent.add("id", destination.getID()); 168 169 JsonObject updateInfo = new JsonObject(); 170 updateInfo.add("parent", parent); 171 if (newName != null) { 172 updateInfo.add("name", newName); 173 } 174 175 request.setBody(updateInfo.toString()); 176 BoxJSONResponse response = (BoxJSONResponse) request.send(); 177 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 178 BoxWebLink movedWebLink = new BoxWebLink(this.getAPI(), responseJSON.get("id").asString()); 179 return movedWebLink.new Info(responseJSON); 180 } 181 182 /** 183 * Renames this weblink. 184 * 185 * @param newName the new name of the weblink. 186 */ 187 public void rename(String newName) { 188 URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 189 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 190 191 JsonObject updateInfo = new JsonObject(); 192 updateInfo.add("name", newName); 193 194 request.setBody(updateInfo.toString()); 195 BoxJSONResponse response = (BoxJSONResponse) request.send(); 196 response.getJSON(); 197 } 198 199 @Override 200 public BoxWebLink.Info getInfo() { 201 URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 202 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 203 BoxJSONResponse response = (BoxJSONResponse) request.send(); 204 return new Info(response.getJSON()); 205 } 206 207 @Override 208 public BoxWebLink.Info getInfo(String... fields) { 209 String queryString = new QueryStringBuilder().appendParam("fields", fields).toString(); 210 URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 211 212 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 213 BoxJSONResponse response = (BoxJSONResponse) request.send(); 214 return new Info(response.getJSON()); 215 } 216 217 /** 218 * Updates the information about this weblink with any info fields that have been modified locally. 219 * 220 * <p>The only fields that will be updated are the ones that have been modified locally. For example, the following 221 * code won't update any information (or even send a network request) since none of the info's fields were 222 * changed:</p> 223 * 224 * <pre>BoxWebLink webLink = new BoxWebLink(api, id); 225 * BoxWebLink.Info info = webLink.getInfo(); 226 * webLink.updateInfo(info);</pre> 227 * 228 * @param info the updated info. 229 */ 230 public void updateInfo(BoxWebLink.Info info) { 231 URL url = WEB_LINK_URL_TEMPLATE.build(this.getAPI().getBaseURL(), this.getID()); 232 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 233 request.setBody(info.getPendingChanges()); 234 BoxJSONResponse response = (BoxJSONResponse) request.send(); 235 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 236 info.update(jsonObject); 237 } 238 239 @Override 240 public BoxWebLink.Info setCollections(BoxCollection... collections) { 241 JsonArray jsonArray = new JsonArray(); 242 for (BoxCollection collection : collections) { 243 JsonObject collectionJSON = new JsonObject(); 244 collectionJSON.add("id", collection.getID()); 245 jsonArray.add(collectionJSON); 246 } 247 JsonObject infoJSON = new JsonObject(); 248 infoJSON.add("collections", jsonArray); 249 250 String queryString = new QueryStringBuilder().appendParam("fields", ALL_FIELDS).toString(); 251 URL url = WEB_LINK_URL_TEMPLATE.buildWithQuery(this.getAPI().getBaseURL(), queryString, this.getID()); 252 BoxJSONRequest request = new BoxJSONRequest(this.getAPI(), url, "PUT"); 253 request.setBody(infoJSON.toString()); 254 BoxJSONResponse response = (BoxJSONResponse) request.send(); 255 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 256 return new Info(jsonObject); 257 } 258 259 /** 260 * Contains information about a BoxWebLink. 261 */ 262 public class Info extends BoxItem.Info { 263 private URL linkURL; 264 private String description; 265 266 /** 267 * Constructs an empty Info object. 268 */ 269 public Info() { 270 super(); 271 } 272 273 /** 274 * Constructs an Info object by parsing information from a JSON string. 275 * 276 * @param json the JSON string to parse. 277 */ 278 public Info(String json) { 279 super(json); 280 } 281 282 /** 283 * Constructs an Info object using an already parsed JSON object. 284 * 285 * @param jsonObject the parsed JSON object. 286 */ 287 public Info(JsonObject jsonObject) { 288 super(jsonObject.toString()); 289 } 290 291 @Override 292 public BoxWebLink getResource() { 293 return BoxWebLink.this; 294 } 295 296 /** 297 * Gets the description of this weblink. 298 * 299 * @return the description of this weblink. 300 */ 301 public String getDescription() { 302 return this.description; 303 } 304 305 /** 306 * Gets the URL this weblink points to. 307 * 308 * @return the URL this weblink points to. 309 */ 310 public URL getLinkURL() { 311 return this.linkURL; 312 } 313 314 @Override 315 protected void parseJSONMember(JsonObject.Member member) { 316 super.parseJSONMember(member); 317 318 String memberName = member.getName(); 319 JsonValue value = member.getValue(); 320 try { 321 if (memberName.equals("url")) { 322 try { 323 if (value.asString().isEmpty()) { 324 this.linkURL = null; 325 } else { 326 this.linkURL = new URL(value.asString()); 327 } 328 } catch (MalformedURLException e) { 329 throw new BoxAPIException("Couldn't parse url for weblink", e); 330 } 331 } else if (memberName.equals("description")) { 332 this.description = value.asString(); 333 } 334 } catch (Exception e) { 335 throw new BoxDeserializationException(memberName, value.toString(), e); 336 } 337 } 338 } 339}