001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonObject; 005import com.eclipsesource.json.JsonValue; 006import java.net.URL; 007import java.util.ArrayList; 008import java.util.List; 009 010/** 011 * Represents a Sign Template used in the Box Sign API. 012 * 013 * @see <a href="https://developer.box.com/reference/resources/sign-templates/">Box Sign 014 * Templates</a> 015 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link 016 * BoxAPIException} (unchecked meaning that the compiler won't force you to handle it) if an 017 * error occurs. If you wish to implement custom error handling for errors related to the Box 018 * REST API, you should capture this exception explicitly. 019 */ 020@BoxResourceType("sign_template") 021public class BoxSignTemplate extends BoxResource { 022 023 /** The URL template for Sign Templates. */ 024 public static final URLTemplate SIGN_TEMPLATES_URL_TEMPLATE = new URLTemplate("sign_templates"); 025 026 /** The URL template for Sign Templates operations with a given ID. */ 027 public static final URLTemplate SIGN_TEMPLATE_URL_TEMPLATE = new URLTemplate("sign_templates/%s"); 028 029 /** The default limit of entries per response. */ 030 public static final int DEFAULT_LIMIT = 100; 031 032 /** 033 * Constructs a BoxSignTemplate for a resource with a given ID. 034 * 035 * @param api the API connection to be used by the resource. 036 * @param id the ID of the resource. 037 */ 038 public BoxSignTemplate(BoxAPIConnection api, String id) { 039 super(api, id); 040 } 041 042 /** 043 * Return all Sign Templates. 044 * 045 * @param api the API connection to be used by the resource. 046 * @return an iterable with all Sign Templates. 047 */ 048 public static Iterable<BoxSignTemplate.Info> getAll(BoxAPIConnection api) { 049 return getAll(api, DEFAULT_LIMIT); 050 } 051 052 /** 053 * Return all Sign Templates. 054 * 055 * @param api the API connection to be used by the resource. 056 * @param limit the limit of entries per response. 057 * @return an iterable with all Sign Templates. 058 */ 059 public static Iterable<BoxSignTemplate.Info> getAll(BoxAPIConnection api, int limit) { 060 QueryStringBuilder builder = new QueryStringBuilder(); 061 URL url = SIGN_TEMPLATES_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString()); 062 return new BoxResourceIterable<BoxSignTemplate.Info>(api, url, limit) { 063 064 @Override 065 protected BoxSignTemplate.Info factory(JsonObject jsonObject) { 066 BoxSignTemplate template = new BoxSignTemplate(api, jsonObject.get("id").asString()); 067 return template.new Info(jsonObject); 068 } 069 }; 070 } 071 072 /** 073 * Return information about this Sign Template. 074 * 075 * @return information about this Sign Template. 076 */ 077 public BoxSignTemplate.Info getInfo() { 078 URL url = SIGN_TEMPLATE_URL_TEMPLATE.buildAlpha(this.getAPI().getBaseURL(), this.getID()); 079 BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET"); 080 try (BoxJSONResponse response = (BoxJSONResponse) request.send()) { 081 JsonObject jsonObject = Json.parse(response.getJSON()).asObject(); 082 return new Info(jsonObject); 083 } 084 } 085 086 /** Contains information about a BoxSignTemplate. */ 087 public class Info extends BoxResource.Info { 088 089 private BoxSignTemplateAdditionalInfo additionalInfo; 090 private boolean areEmailSettingsLocked; 091 private boolean areFieldsLocked; 092 private boolean areOptionsLocked; 093 private boolean areFilesLocked; 094 private boolean areRecipientsLocked; 095 private BoxSignTemplateCustomBranding customBranding; 096 private Integer daysValid; 097 private String emailMessage; 098 private String emailSubject; 099 private String name; 100 private BoxFolder.Info parentFolder; 101 private BoxSignTemplateReadySignLink readySignLink; 102 private List<BoxSignTemplateSigner> signers; 103 private List<BoxFile.Info> sourceFiles; 104 105 /** Constructs an empty Info object. */ 106 public Info() { 107 super(); 108 } 109 110 /** 111 * Constructs an Info object with the provided JSON string. 112 * 113 * @param json the JSON string representing the Sign Template. 114 */ 115 public Info(String json) { 116 super(json); 117 } 118 119 /** 120 * Constructs an Info object with the provided JSON object. 121 * 122 * @param jsonObject the JSON object representing the Sign Template. 123 */ 124 Info(JsonObject jsonObject) { 125 super(jsonObject); 126 } 127 128 /** {@inheritDoc} */ 129 @Override 130 public BoxSignTemplate getResource() { 131 return BoxSignTemplate.this; 132 } 133 134 /** 135 * Gets the additional information about this Sign Template. 136 * 137 * @return the additional information about this Sign Template. 138 */ 139 public BoxSignTemplateAdditionalInfo getAdditionalInfo() { 140 return this.additionalInfo; 141 } 142 143 /** 144 * Gets whether the templates email settings are editable or not. 145 * 146 * @return true if the email settings are locked; otherwise false. 147 */ 148 public boolean getAreEmailSettingsLocked() { 149 return this.areEmailSettingsLocked; 150 } 151 152 /** 153 * Gets whether the templates input fields are editable or not. This includes deleting or 154 * renaming template files. 155 * 156 * @return true if the fields are locked; otherwise false. 157 */ 158 public boolean getAreFieldsLocked() { 159 return this.areFieldsLocked; 160 } 161 162 /** 163 * Gets weather the templates input options are editable or not. 164 * 165 * @return true if the options are editable; otherwise false. 166 */ 167 public boolean getAreOptionsLocked() { 168 return this.areOptionsLocked; 169 } 170 171 /** 172 * Gets whether the template document options are editable or not, for example renaming the 173 * document. 174 * 175 * @return true if the files are locked; otherwise false. 176 */ 177 public boolean getAreFilesLocked() { 178 return this.areFilesLocked; 179 } 180 181 /** 182 * Gets whether the template signers are editable or not. 183 * 184 * @return true if the recipients are locked; otherwise false. 185 */ 186 public boolean getAreRecipientsLocked() { 187 return this.areRecipientsLocked; 188 } 189 190 /** 191 * Gets the custom branding applied to notifications and signature requests. 192 * 193 * @return the custom branding for this Sign Template. 194 */ 195 public BoxSignTemplateCustomBranding getCustomBranding() { 196 return this.customBranding; 197 } 198 199 /** 200 * Gets the number of days after which the created signature request will automatically expire 201 * if not completed. By default, we do not apply any expiration date on signature requests, and 202 * the signature request does not expire. 203 * 204 * @return the number of days the template is valid for. 205 */ 206 public Integer getDaysValid() { 207 return this.daysValid; 208 } 209 210 /** 211 * Gets the email message that will be sent to all signers. 212 * 213 * @return the email message for this Sign Template. 214 */ 215 public String getEmailMessage() { 216 return this.emailMessage; 217 } 218 219 /** 220 * Gets the email subject that will be sent to all signers. 221 * 222 * @return the email subject for this Sign Template. 223 */ 224 public String getEmailSubject() { 225 return this.emailSubject; 226 } 227 228 /** 229 * Gets the name of this Sign Template. 230 * 231 * @return the name of this Sign Template. 232 */ 233 public String getName() { 234 return this.name; 235 } 236 237 /** 238 * Gets the parent folder of this Sign Template. 239 * 240 * @return the parent folder of this Sign Template. 241 */ 242 public BoxFolder.Info getParentFolder() { 243 return this.parentFolder; 244 } 245 246 /** 247 * Gets the ready sign link for this Sign Template. 248 * 249 * @return the ready sign link for this Sign Template. 250 */ 251 public BoxSignTemplateReadySignLink getReadySignLink() { 252 return this.readySignLink; 253 } 254 255 /** 256 * Gets the signers for this Sign Template. 257 * 258 * @return the signers for this Sign Template. 259 */ 260 public List<BoxSignTemplateSigner> getSigners() { 261 return this.signers; 262 } 263 264 /** 265 * Gets the source files for this Sign Template. 266 * 267 * @return the source files for this Sign Template. 268 */ 269 public List<BoxFile.Info> getSourceFiles() { 270 return this.sourceFiles; 271 } 272 273 /** {@inheritDoc} */ 274 @Override 275 void parseJSONMember(JsonObject.Member member) { 276 super.parseJSONMember(member); 277 String memberName = member.getName(); 278 JsonValue value = member.getValue(); 279 try { 280 switch (memberName) { 281 case "additional_info": 282 this.additionalInfo = this.parseAdditionalInfo(value.asObject()); 283 break; 284 case "are_email_settings_locked": 285 this.areEmailSettingsLocked = value.asBoolean(); 286 break; 287 case "are_fields_locked": 288 this.areFieldsLocked = value.asBoolean(); 289 break; 290 case "are_options_locked": 291 this.areOptionsLocked = value.asBoolean(); 292 break; 293 case "are_files_locked": 294 this.areFilesLocked = value.asBoolean(); 295 break; 296 case "are_recipients_locked": 297 this.areRecipientsLocked = value.asBoolean(); 298 break; 299 case "custom_branding": 300 this.customBranding = this.parseCustomBranding(value.asObject()); 301 break; 302 case "days_valid": 303 this.daysValid = value.asInt(); 304 break; 305 case "email_message": 306 this.emailMessage = value.asString(); 307 break; 308 case "email_subject": 309 this.emailSubject = value.asString(); 310 break; 311 case "name": 312 this.name = value.asString(); 313 break; 314 case "parent_folder": 315 JsonObject parentFolderJSON = value.asObject(); 316 String parentFolderID = parentFolderJSON.get("id").asString(); 317 BoxFolder parentFolder = new BoxFolder(getAPI(), parentFolderID); 318 this.parentFolder = parentFolder.new Info(parentFolderJSON); 319 break; 320 case "ready_sign_link": 321 this.readySignLink = this.parseReadySignLink(value.asObject()); 322 break; 323 case "signers": 324 this.signers = this.parseSigners(value.asArray()); 325 break; 326 case "source_files": 327 this.sourceFiles = this.parseSourceFiles(value.asArray()); 328 break; 329 default: 330 } 331 } catch (Exception e) { 332 throw new BoxDeserializationException(memberName, value.toString(), e); 333 } 334 } 335 336 private BoxSignTemplateAdditionalInfo parseAdditionalInfo(JsonValue additionalInfoJSON) { 337 List<String> nonEditableFields = new ArrayList<String>(); 338 for (JsonValue fieldJSON : additionalInfoJSON.asObject().get("non_editable").asArray()) { 339 nonEditableFields.add(fieldJSON.asString()); 340 } 341 BoxSignTemplateAdditionalInfoRequired required = 342 this.parseAdditionalInfoRequired( 343 additionalInfoJSON.asObject().get("required").asObject()); 344 return new BoxSignTemplateAdditionalInfo(nonEditableFields, required); 345 } 346 347 private BoxSignTemplateAdditionalInfoRequired parseAdditionalInfoRequired( 348 JsonObject requiredJSON) { 349 List<List<String>> signers = new ArrayList<List<String>>(); 350 for (JsonValue signerJSON : requiredJSON.get("signers").asArray()) { 351 List<String> signer = new ArrayList<String>(); 352 for (JsonValue fieldJSON : signerJSON.asArray()) { 353 signer.add(fieldJSON.asString()); 354 } 355 signers.add(signer); 356 } 357 return new BoxSignTemplateAdditionalInfoRequired(signers); 358 } 359 360 private List<BoxFile.Info> parseSourceFiles(JsonValue filesArray) { 361 List<BoxFile.Info> files = new ArrayList<BoxFile.Info>(); 362 for (JsonValue fileJSON : filesArray.asArray()) { 363 JsonObject fileObj = fileJSON.asObject(); 364 String fileID = fileObj.get("id").asString(); 365 BoxFile file = new BoxFile(getAPI(), fileID); 366 files.add(file.new Info(fileObj)); 367 } 368 return files; 369 } 370 371 private List<BoxSignTemplateSigner> parseSigners(JsonValue signersArray) { 372 List<BoxSignTemplateSigner> signers = new ArrayList<BoxSignTemplateSigner>(); 373 for (JsonValue signerJSON : signersArray.asArray()) { 374 JsonObject signerObj = signerJSON.asObject(); 375 signers.add(new BoxSignTemplateSigner(signerObj, getAPI())); 376 } 377 return signers; 378 } 379 380 private BoxSignTemplateCustomBranding parseCustomBranding(JsonObject customBrandingJSON) { 381 String brandingColor = customBrandingJSON.get("branding_color").asString(); 382 String companyName = customBrandingJSON.get("company_name").asString(); 383 String emailFooterText = customBrandingJSON.get("email_footer_text").asString(); 384 String logoUri = customBrandingJSON.get("logo_uri").asString(); 385 return new BoxSignTemplateCustomBranding( 386 brandingColor, companyName, emailFooterText, logoUri); 387 } 388 389 private BoxSignTemplateReadySignLink parseReadySignLink(JsonObject readySignLinkJSON) { 390 String folderID = readySignLinkJSON.get("folder_id").asString(); 391 String instructions = readySignLinkJSON.get("instructions").asString(); 392 boolean isActive = readySignLinkJSON.get("is_active").asBoolean(); 393 boolean isNofiticationDisabled = 394 readySignLinkJSON.get("is_notification_disabled").asBoolean(); 395 String name = readySignLinkJSON.get("name").asString(); 396 String url = readySignLinkJSON.get("url").asString(); 397 return new BoxSignTemplateReadySignLink( 398 folderID, instructions, isActive, isNofiticationDisabled, name, url); 399 } 400 } 401}