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