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