001package com.box.sdk; 002 003import static java.lang.String.format; 004 005import com.box.sdk.internal.utils.JsonUtils; 006import com.eclipsesource.json.JsonObject; 007import com.eclipsesource.json.JsonValue; 008import java.util.ArrayList; 009import java.util.Date; 010import java.util.List; 011 012/** 013 * Represents a signer in BoxSignRequest. 014 */ 015public class BoxSignRequestSigner extends BoxJSONObject { 016 private String email; 017 private BoxSignRequestSignerRole role; 018 private Boolean isInPerson; 019 private Integer order; 020 private String embedUrlExternalUserId; 021 private Boolean hasViewedEmail; 022 private Boolean hasViewedDocument; 023 private BoxSignerDecision signerDecision; 024 private List<BoxSignerInput> inputs; 025 private String embedUrl; 026 private String redirectUrl; 027 private String declinedRedirectUrl; 028 private String iframeableEmedUrl; 029 private BoxAPIConnection api; 030 031 /** 032 * Constructs a BoxSignRequestSigner with an email. 033 * 034 * @param email of signer. 035 */ 036 public BoxSignRequestSigner(String email) { 037 this.email = email; 038 } 039 040 /** 041 * Construct a BoxSignRequestSigner. 042 * 043 * @param jsonObject the parsed JSON object. 044 * @param api the API connection to be used to fetch interacted item 045 */ 046 public BoxSignRequestSigner(JsonObject jsonObject, BoxAPIConnection api) { 047 super(jsonObject); 048 this.api = api; 049 } 050 051 /** 052 * Gets the email address of the signer. 053 * 054 * @return email address of the signer. 055 */ 056 public String getEmail() { 057 return this.email; 058 } 059 060 /** 061 * Sets the email address of the signer. 062 * 063 * @param email address of the signer. 064 * @return this BoxSignRequestSigner object for chaining. 065 */ 066 public BoxSignRequestSigner setEmail(String email) { 067 this.email = email; 068 return this; 069 } 070 071 /** 072 * Gets the role of the signer. 073 * 074 * @return role of the signer. 075 */ 076 public BoxSignRequestSignerRole getRole() { 077 return this.role; 078 } 079 080 /** 081 * Sets the role of the signer. If role is not set it's FinalCopyReader by default. 082 * 083 * @param role of the signer. 084 * @return this BoxSignRequestSigner object for chaining. 085 */ 086 public BoxSignRequestSigner setRole(BoxSignRequestSignerRole role) { 087 this.role = role; 088 return this; 089 } 090 091 /** 092 * Gets the flag that when used in combination with an embed url on the sender. After the sender signs, 093 * they will be redirected to the next InPerson signer. 094 * 095 * @return true if is in person signer, otherwise false. 096 */ 097 public boolean getIsInPerson() { 098 return this.isInPerson; 099 } 100 101 /** 102 * Gets the order of signer. 103 * 104 * @return order of signer. 105 */ 106 public int getOrder() { 107 return this.order; 108 } 109 110 /** 111 * Sets the order of signer. 112 * 113 * @param order of signer. 114 * @return this BoxSignRequestSigner object for chaining. 115 */ 116 public BoxSignRequestSigner setOrder(Integer order) { 117 this.order = order; 118 return this; 119 } 120 121 /** 122 * Gets the user id for this signer in external application responsible 123 * for authentication when accessing the embed url. 124 * 125 * @return embed url external user id. 126 */ 127 public String getEmbedUrlExternalUserId() { 128 return this.embedUrlExternalUserId; 129 } 130 131 /** 132 * Sets the user id for this signer in external application responsible 133 * for authentication when accessing the embed url. 134 * 135 * @param embedUrlExternalUserId for this signer in external application responsible 136 * for authentication when accessing the embed url. 137 * @return this BoxSignRequestSigner object for chaining. 138 */ 139 public BoxSignRequestSigner setEmbedUrlExternalUserId(String embedUrlExternalUserId) { 140 this.embedUrlExternalUserId = embedUrlExternalUserId; 141 return this; 142 } 143 144 /** 145 * Gets the flag indicating if signer has viewed the sign request email. 146 * 147 * @return true if the signer has viewed the sign request email, otherwise false. 148 */ 149 public boolean getHasViewedEmail() { 150 return this.hasViewedEmail; 151 } 152 153 /** 154 * Gets the flag indicating if signer has viewed the document. 155 * 156 * @return true if the signer has viewed the document, otherwise false. 157 */ 158 public boolean getHasViewedDocument() { 159 return this.hasViewedDocument; 160 } 161 162 /** 163 * Gets the final decision made by signer. 164 * 165 * @return final decision made by signer. 166 */ 167 public BoxSignerDecision getSignerDecision() { 168 return this.signerDecision; 169 } 170 171 /** 172 * Gets the inputs created by a signer on a sign request. 173 * 174 * @return list of inputs created by a signer on a sign request. 175 */ 176 public List<BoxSignerInput> getInputs() { 177 return this.inputs; 178 } 179 180 /** 181 * Gets the url to direct signer to for signing. 182 * 183 * @return url to direct signer to for signing. 184 */ 185 public String getEmbedUrl() { 186 return this.embedUrl; 187 } 188 189 /** 190 * Gets the flag that is used in combination with an embed url for a the sender. After the sender signs, 191 * they will be redirected to the next InPerson signer. 192 * 193 * @return true if is in person signer, otherwise false. 194 */ 195 public Boolean getInPerson() { 196 return this.isInPerson; 197 } 198 199 /** 200 * Sets the flag that is used in combination with an embed url for a the sender. After the sender signs, 201 * they will be redirected to the next InPerson signer. 202 * 203 * @param isInPerson flag. 204 * @return this BoxSignRequestSigner object for chaining. 205 */ 206 public BoxSignRequestSigner setInPerson(Boolean isInPerson) { 207 this.isInPerson = isInPerson; 208 return this; 209 } 210 211 /** 212 * Gets the redirect url for the signer. 213 * 214 * @return redirect url for the signer. 215 */ 216 public String getRedirectUrl() { 217 return this.redirectUrl; 218 } 219 220 /** 221 * Sets the redirect url for the signer. 222 * 223 * @param redirectUrl for the signer. 224 * @return this BoxSignRequestSigner object for chaining. 225 */ 226 public BoxSignRequestSigner setRedirectUrl(String redirectUrl) { 227 this.redirectUrl = redirectUrl; 228 return this; 229 } 230 231 /** 232 * Gets the declined redirect url for the signer. 233 * 234 * @return declined redirect url for the signer. 235 */ 236 public String getDeclinedRedirectUrl() { 237 return this.declinedRedirectUrl; 238 } 239 240 /** 241 * Sets the declined redirect url for the signer. 242 * 243 * @param declinedRedirectUrl for the signer. 244 * @return this BoxSignRequestSigner object for chaining. 245 */ 246 public BoxSignRequestSigner setDeclinedRedirectUrl(String declinedRedirectUrl) { 247 this.declinedRedirectUrl = declinedRedirectUrl; 248 return this; 249 } 250 251 /** 252 * Gets the URL designed for signing documents within an HTML iframe tag. 253 * It will be returned in the response only if the embedUrlExternalUserId parameter was passed 254 * in the create sign request call. 255 * 256 * @return url for signing documents within an HTML iframe tag. 257 */ 258 public String getIframeableEmedUrl() { 259 return this.iframeableEmedUrl; 260 } 261 262 /** 263 * Sets the URL designed for signing documents within an HTML iframe tag. 264 * It will be returned in the response only if the embedUrlExternalUserId parameter was passed 265 * in the create sign request call. 266 * 267 * @param iframeableEmedUrl url for signing documents within an HTML iframe tag. 268 * @return this BoxSignRequestSigner object for chaining. 269 */ 270 public BoxSignRequestSigner setIframeableEmedUrl(String iframeableEmedUrl) { 271 this.iframeableEmedUrl = iframeableEmedUrl; 272 return this; 273 } 274 275 /** 276 * {@inheritDoc} 277 */ 278 @Override 279 void parseJSONMember(JsonObject.Member member) { 280 JsonValue value = member.getValue(); 281 String memberName = member.getName(); 282 try { 283 switch (memberName) { 284 case "email": 285 this.email = value.asString(); 286 break; 287 case "role": 288 this.role = BoxSignRequestSignerRole.fromJSONString(value.asString()); 289 break; 290 case "is_in_person": 291 this.isInPerson = value.asBoolean(); 292 break; 293 case "order": 294 this.order = value.asInt(); 295 break; 296 case "embed_url_external_user_id": 297 this.embedUrlExternalUserId = value.asString(); 298 break; 299 case "has_viewed_email": 300 this.hasViewedEmail = value.asBoolean(); 301 break; 302 case "has_viewed_document": 303 this.hasViewedDocument = value.asBoolean(); 304 break; 305 case "signer_decision": 306 JsonObject signerDecisionJSON = value.asObject(); 307 this.signerDecision = new BoxSignerDecision(signerDecisionJSON); 308 break; 309 case "inputs": 310 List<BoxSignerInput> inputs = new ArrayList<>(); 311 for (JsonValue inputJSON : value.asArray()) { 312 BoxSignerInput input = new BoxSignerInput(inputJSON.asObject()); 313 inputs.add(input); 314 } 315 this.inputs = inputs; 316 break; 317 case "embed_url": 318 this.embedUrl = value.asString(); 319 break; 320 case "redirect_url": 321 this.redirectUrl = value.asString(); 322 break; 323 case "declined_redirect_url": 324 this.declinedRedirectUrl = value.asString(); 325 break; 326 case "iframeable_embed_url": 327 this.iframeableEmedUrl = value.asString(); 328 break; 329 default: 330 return; 331 } 332 } catch (Exception e) { 333 throw new BoxDeserializationException(memberName, value.toString(), e); 334 } 335 } 336 337 /** 338 * Gets a JSON object representing this class. 339 * 340 * @return the JSON object representing this class. 341 */ 342 public JsonObject getJSONObject() { 343 JsonObject jsonObj = new JsonObject(); 344 JsonUtils.addIfNotNull(jsonObj, "email", this.email); 345 JsonUtils.addIfNotNull(jsonObj, "role", this.role); 346 JsonUtils.addIfNotNull(jsonObj, "is_in_person", this.isInPerson); 347 JsonUtils.addIfNotNull(jsonObj, "order", this.order); 348 JsonUtils.addIfNotNull(jsonObj, "embed_url_external_user_id", this.embedUrlExternalUserId); 349 JsonUtils.addIfNotNull(jsonObj, "redirect_url", this.redirectUrl); 350 JsonUtils.addIfNotNull(jsonObj, "declined_redirect_url", this.declinedRedirectUrl); 351 return jsonObj; 352 } 353 354 /** 355 * Type of decision made by signer. 356 */ 357 public enum BoxSignRequestSignerDecisionType { 358 359 /** 360 * Signed decision. 361 */ 362 Signed("signed"), 363 364 /** 365 * Declined decision. 366 */ 367 Declined("declined"); 368 369 private final String jsonValue; 370 371 BoxSignRequestSignerDecisionType(String jsonValue) { 372 this.jsonValue = jsonValue; 373 } 374 375 static BoxSignRequestSignerDecisionType fromJSONString(String jsonValue) { 376 if ("signed".equals(jsonValue)) { 377 return Signed; 378 } else if ("declined".equals(jsonValue)) { 379 return Declined; 380 } 381 throw new IllegalArgumentException( 382 "The provided JSON value isn't a valid " + "BoxSignRequestSignerDecisionType."); 383 } 384 } 385 386 /** 387 * Represents a type of input. 388 */ 389 public enum BoxSignRequestInputType { 390 391 /** 392 * Signature input. 393 */ 394 Signature("signature"), 395 396 /** 397 * Text input. 398 */ 399 Text("text"), 400 401 /** 402 * Checkbox input. 403 */ 404 Checkbox("checkbox"), 405 406 /** 407 * Date input. 408 */ 409 Date("date"); 410 411 private final String jsonValue; 412 413 BoxSignRequestInputType(String jsonValue) { 414 this.jsonValue = jsonValue; 415 } 416 417 static BoxSignRequestInputType fromJSONString(String jsonValue) { 418 if ("signature".equals(jsonValue)) { 419 return Signature; 420 } else if ("text".equals(jsonValue)) { 421 return Text; 422 } else if ("checkbox".equals(jsonValue)) { 423 return Checkbox; 424 } else if ("date".equals(jsonValue)) { 425 return Date; 426 } 427 throw new IllegalArgumentException("The provided JSON value isn't a valid " + "BoxSignRequestInputType."); 428 } 429 } 430 431 /** 432 * Represents a content type of input. 433 */ 434 public enum BoxSignRequestInputContentType { 435 /** 436 * Initial content type 437 */ 438 Initial("initial"), 439 /** 440 * Stamp content type 441 */ 442 Stamp("stamp"), 443 /** 444 * Signature content type 445 */ 446 Signature("signature"), 447 /** 448 * Company content type 449 */ 450 Company("company"), 451 /** 452 * Title content type 453 */ 454 Title("title"), 455 /** 456 * Email content type 457 */ 458 Email("email"), 459 /** 460 * Full name content type 461 */ 462 FullName("full_name"), 463 /** 464 * First name content type 465 */ 466 FirstName("first_name"), 467 /** 468 * Last name content type 469 */ 470 LastName("last_name"), 471 /** 472 * Text content type 473 */ 474 Text("text"), 475 /** 476 * Date content type 477 */ 478 Date("date"), 479 /** 480 * Checkbox content type 481 */ 482 Checkbox("checkbox"); 483 484 private final String jsonValue; 485 486 BoxSignRequestInputContentType(String jsonValue) { 487 this.jsonValue = jsonValue; 488 } 489 490 static BoxSignRequestInputContentType fromJSONString(String jsonValue) { 491 switch (jsonValue) { 492 case "initial": 493 return Initial; 494 case "stamp": 495 return Stamp; 496 case "signature": 497 return Signature; 498 case "company": 499 return Company; 500 case "title": 501 return Title; 502 case "email": 503 return Email; 504 case "full_name": 505 return FullName; 506 case "first_name": 507 return FirstName; 508 case "last_name": 509 return LastName; 510 case "text": 511 return Text; 512 case "date": 513 return Date; 514 case "checkbox": 515 return Checkbox; 516 default: 517 throw new IllegalArgumentException( 518 format("The provided JSON value '%s' isn't a valid BoxSignRequestInputContentType.", jsonValue) 519 ); 520 } 521 } 522 } 523 524 /** 525 * Represents a final decision made by signer (type and time the decision was made). 526 */ 527 public class BoxSignerDecision extends BoxJSONObject { 528 private BoxSignRequestSignerDecisionType type; 529 private Date finalizedAt; 530 531 /** 532 * Constructs a BoxSignerDecision object using an already parsed JSON object. 533 * 534 * @param jsonObject the parsed JSON object. 535 */ 536 public BoxSignerDecision(JsonObject jsonObject) { 537 super(jsonObject); 538 } 539 540 /** 541 * Gets the type of decision made by signer. 542 * 543 * @return type of decision made by signer. 544 */ 545 public BoxSignRequestSignerDecisionType getType() { 546 return this.type; 547 } 548 549 /** 550 * Gets the date/time that the decision was made. 551 * 552 * @return date/time that the decision was made. 553 */ 554 public Date getFinalizedAt() { 555 return this.finalizedAt; 556 } 557 558 /** 559 * {@inheritDoc} 560 */ 561 @Override 562 void parseJSONMember(JsonObject.Member member) { 563 JsonValue value = member.getValue(); 564 String memberName = member.getName(); 565 try { 566 if (memberName.equals("type")) { 567 this.type = BoxSignRequestSignerDecisionType.fromJSONString(value.asString()); 568 } else if (memberName.equals("finalized_at")) { 569 this.finalizedAt = BoxDateFormat.parse(value.asString()); 570 } 571 } catch (Exception e) { 572 throw new BoxDeserializationException(memberName, value.toString(), e); 573 } 574 } 575 } 576 577 /** 578 * Represents an input created by a signer on a sign request. 579 */ 580 public class BoxSignerInput extends BoxJSONObject { 581 private String documentTagId; 582 private String textValue; 583 private boolean checkboxValue; 584 private BoxSignRequestInputContentType contentType; 585 private Date dateValue; 586 private BoxSignRequestInputType type; 587 private int pageIndex; 588 589 /** 590 * Constructs a BoxSignerInput object using an already parsed JSON object. 591 * 592 * @param jsonObject the parsed JSON object. 593 */ 594 public BoxSignerInput(JsonObject jsonObject) { 595 super(jsonObject); 596 } 597 598 /** 599 * Gets the reference of the id of a particular tag added to the content 600 * of the files being used to create the sign request. 601 * 602 * @return document tag id. 603 */ 604 public String getDocumentTagId() { 605 return this.documentTagId; 606 } 607 608 /** 609 * Gets the text prefill value. 610 * 611 * @return text prefill value. 612 */ 613 public String getTextValue() { 614 return this.textValue; 615 } 616 617 /** 618 * Gets the checkbox prefill value. 619 * 620 * @return checkbox prefill value. 621 */ 622 public boolean getIsCheckboxValue() { 623 return this.checkboxValue; 624 } 625 626 /** 627 * Gets the content type of the input. 628 * 629 * @return content type of the input. 630 */ 631 public BoxSignRequestInputContentType getContentType() { 632 return this.contentType; 633 } 634 635 /** 636 * Gets the date prefill value. 637 * 638 * @return date prefill value. 639 */ 640 public Date getDateValue() { 641 return this.dateValue; 642 } 643 644 /** 645 * Gets the type of input. 646 * 647 * @return type of input. 648 */ 649 public BoxSignRequestInputType getType() { 650 return this.type; 651 } 652 653 /** 654 * Gets the index of page that input is on. 655 * 656 * @return index of page that input is on. 657 */ 658 public int getPageIndex() { 659 return this.pageIndex; 660 } 661 662 /** 663 * {@inheritDoc} 664 */ 665 @Override 666 void parseJSONMember(JsonObject.Member member) { 667 JsonValue value = member.getValue(); 668 String memberName = member.getName(); 669 try { 670 switch (memberName) { 671 case "documentTagId": 672 this.documentTagId = value.asString(); 673 break; 674 case "text_value": 675 this.textValue = value.asString(); 676 break; 677 case "checkbox_value": 678 this.checkboxValue = value.asBoolean(); 679 break; 680 case "content_type": 681 this.contentType = BoxSignRequestInputContentType.fromJSONString(value.asString()); 682 break; 683 case "date_value": 684 this.dateValue = BoxDateFormat.parseDateOnly(value.asString()); 685 break; 686 case "type": 687 this.type = BoxSignRequestInputType.fromJSONString(value.asString()); 688 break; 689 case "page_index": 690 this.pageIndex = value.asInt(); 691 break; 692 default: 693 return; 694 } 695 } catch (Exception e) { 696 throw new BoxDeserializationException(memberName, value.toString(), e); 697 } 698 } 699 } 700} 701 702