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