001package com.box.sdk; 002 003import com.eclipsesource.json.Json; 004import com.eclipsesource.json.JsonArray; 005import com.eclipsesource.json.JsonObject; 006import com.eclipsesource.json.JsonValue; 007import java.net.URL; 008import java.util.ArrayList; 009import java.util.List; 010 011/** 012 * The MetadataTemplate class represents the Box metadata template object. 013 * Templates allow the metadata service to provide a multitude of services, 014 * such as pre-defining sets of key:value pairs or schema enforcement on specific fields. 015 * 016 * @see <a href="https://developer.box.com/reference/resources/metadata-templates/">Box metadata templates</a> 017 */ 018public class MetadataTemplate extends BoxJSONObject { 019 020 /** 021 * @see #getMetadataTemplate(BoxAPIConnection) 022 */ 023 public static final URLTemplate METADATA_TEMPLATE_URL_TEMPLATE 024 = new URLTemplate("metadata_templates/%s/%s/schema"); 025 026 /** 027 * @see #getMetadataTemplateByID(BoxAPIConnection, String) 028 */ 029 public static final URLTemplate METADATA_TEMPLATE_BY_ID_URL_TEMPLATE = new URLTemplate("metadata_templates/%s"); 030 031 /** 032 * @see #createMetadataTemplate(BoxAPIConnection, String, String, String, boolean, List) 033 */ 034 public static final URLTemplate METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE 035 = new URLTemplate("metadata_templates/schema"); 036 037 /** 038 * @see #getEnterpriseMetadataTemplates(String, int, BoxAPIConnection, String...) 039 */ 040 public static final URLTemplate ENTERPRISE_METADATA_URL_TEMPLATE = new URLTemplate("metadata_templates/%s"); 041 042 /** 043 * 044 */ 045 private static final URLTemplate METADATA_QUERIES_URL_TEMPLATE = new URLTemplate("metadata_queries/execute_read"); 046 047 /** 048 * Default metadata type to be used in query. 049 */ 050 private static final String DEFAULT_METADATA_TYPE = "properties"; 051 052 /** 053 * Global metadata scope. Used by default if the metadata type is "properties". 054 */ 055 private static final String GLOBAL_METADATA_SCOPE = "global"; 056 057 /** 058 * Enterprise metadata scope. Used by default if the metadata type is not "properties". 059 */ 060 private static final String ENTERPRISE_METADATA_SCOPE = "enterprise"; 061 062 /** 063 * Default number of entries per page. 064 */ 065 private static final int DEFAULT_ENTRIES_LIMIT = 100; 066 067 /** 068 * @see #getID() 069 */ 070 private String id; 071 072 /** 073 * @see #getTemplateKey() 074 */ 075 private String templateKey; 076 077 /** 078 * @see #getScope() 079 */ 080 private String scope; 081 082 /** 083 * @see #getDisplayName() 084 */ 085 private String displayName; 086 087 /** 088 * @see #getIsHidden() 089 */ 090 private Boolean isHidden; 091 092 /** 093 * @see #getFields() 094 */ 095 private List<Field> fields; 096 097 /** 098 * @see #getCopyInstanceOnItemCopy() 099 */ 100 private Boolean copyInstanceOnItemCopy; 101 102 /** 103 * Constructs an empty metadata template. 104 */ 105 public MetadataTemplate() { 106 super(); 107 } 108 109 /** 110 * Constructs a metadata template from a JSON string. 111 * 112 * @param json the json encoded metadate template. 113 */ 114 public MetadataTemplate(String json) { 115 super(json); 116 } 117 118 /** 119 * Constructs a metadate template from a JSON object. 120 * 121 * @param jsonObject the json encoded metadate template. 122 */ 123 MetadataTemplate(JsonObject jsonObject) { 124 super(jsonObject); 125 } 126 127 /** 128 * Creates new metadata template. 129 * 130 * @param api the API connection to be used. 131 * @param scope the scope of the object. 132 * @param templateKey a unique identifier for the template. 133 * @param displayName the display name of the field. 134 * @param hidden whether this template is hidden in the UI. 135 * @param fields the ordered set of fields for the template 136 * @return the metadata template returned from the server. 137 */ 138 public static MetadataTemplate createMetadataTemplate( 139 BoxAPIConnection api, 140 String scope, 141 String templateKey, 142 String displayName, 143 boolean hidden, 144 List<Field> fields 145 ) { 146 return createMetadataTemplate(api, scope, templateKey, displayName, hidden, fields, null); 147 } 148 149 /** 150 * Creates new metadata template. 151 * 152 * @param api the API connection to be used. 153 * @param scope the scope of the object. 154 * @param templateKey a unique identifier for the template. 155 * @param displayName the display name of the field. 156 * @param hidden whether this template is hidden in the UI. 157 * @param fields the ordered set of fields for the template 158 * @param copyInstanceOnItemCopy determines whether the copy operation should copy the metadata along with the item. 159 * @return the metadata template returned from the server. 160 */ 161 public static MetadataTemplate createMetadataTemplate( 162 BoxAPIConnection api, 163 String scope, 164 String templateKey, 165 String displayName, 166 Boolean hidden, 167 List<Field> fields, 168 Boolean copyInstanceOnItemCopy 169 ) { 170 171 JsonObject jsonObject = new JsonObject(); 172 jsonObject.add("scope", scope); 173 jsonObject.add("displayName", displayName); 174 175 if (hidden != null) { 176 jsonObject.add("hidden", hidden); 177 } 178 179 if (copyInstanceOnItemCopy != null) { 180 jsonObject.add("copyInstanceOnItemCopy", copyInstanceOnItemCopy); 181 } 182 183 if (templateKey != null) { 184 jsonObject.add("templateKey", templateKey); 185 } 186 187 JsonArray fieldsArray = new JsonArray(); 188 if (fields != null && !fields.isEmpty()) { 189 for (Field field : fields) { 190 JsonObject fieldObj = getFieldJsonObject(field); 191 192 fieldsArray.add(fieldObj); 193 } 194 195 jsonObject.add("fields", fieldsArray); 196 } 197 198 URL url = METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE.build(api.getBaseURL()); 199 BoxJSONRequest request = new BoxJSONRequest(api, url, "POST"); 200 request.setBody(jsonObject.toString()); 201 202 try (BoxJSONResponse response = request.send()) { 203 JsonObject responseJSON = Json.parse(response.getJSON()).asObject(); 204 205 return new MetadataTemplate(responseJSON); 206 } 207 } 208 209 /** 210 * Gets the JsonObject representation of the given field object. 211 * 212 * @param field represents a template field 213 * @return the json object 214 */ 215 private static JsonObject getFieldJsonObject(Field field) { 216 JsonObject fieldObj = new JsonObject(); 217 fieldObj.add("type", field.getType()); 218 fieldObj.add("key", field.getKey()); 219 fieldObj.add("displayName", field.getDisplayName()); 220 221 String fieldDesc = field.getDescription(); 222 if (fieldDesc != null) { 223 fieldObj.add("description", field.getDescription()); 224 } 225 226 Boolean fieldIsHidden = field.getIsHidden(); 227 if (fieldIsHidden != null) { 228 fieldObj.add("hidden", field.getIsHidden()); 229 } 230 231 JsonArray array = new JsonArray(); 232 List<String> options = field.getOptions(); 233 if (options != null && !options.isEmpty()) { 234 for (String option : options) { 235 JsonObject optionObj = new JsonObject(); 236 optionObj.add("key", option); 237 238 array.add(optionObj); 239 } 240 fieldObj.add("options", array); 241 } 242 243 return fieldObj; 244 } 245 246 /** 247 * Updates the schema of an existing metadata template. 248 * 249 * @param api the API connection to be used 250 * @param scope the scope of the object 251 * @param template Unique identifier of the template 252 * @param fieldOperations the fields that needs to be updated / added in the template 253 * @return the updated metadata template 254 */ 255 public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template, 256 List<FieldOperation> fieldOperations) { 257 258 JsonArray array = new JsonArray(); 259 260 for (FieldOperation fieldOperation : fieldOperations) { 261 JsonObject jsonObject = getFieldOperationJsonObject(fieldOperation); 262 array.add(jsonObject); 263 } 264 265 URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlpha(api.getBaseURL(), scope, template); 266 BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT"); 267 request.setBody(array.toString()); 268 269 try (BoxJSONResponse response = request.send()) { 270 JsonObject responseJson = Json.parse(response.getJSON()).asObject(); 271 272 return new MetadataTemplate(responseJson); 273 } 274 } 275 276 /** 277 * Deletes the schema of an existing metadata template. 278 * 279 * @param api the API connection to be used 280 * @param scope the scope of the object 281 * @param template Unique identifier of the template 282 */ 283 public static void deleteMetadataTemplate(BoxAPIConnection api, String scope, String template) { 284 URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlpha(api.getBaseURL(), scope, template); 285 BoxAPIRequest request = new BoxAPIRequest(api, url, "DELETE"); 286 request.send().close(); 287 } 288 289 /** 290 * Executes a metadata query. 291 * 292 * @param api The API connection to be used 293 * @param queryBody The query 294 * @return An iterable of BoxItem.Info search results 295 */ 296 public static BoxResourceIterable<BoxItem.Info> executeMetadataQuery( 297 final BoxAPIConnection api, 298 final MetadataQuery queryBody 299 ) { 300 301 URL url = METADATA_QUERIES_URL_TEMPLATE.build(api.getBaseURL()); 302 return new BoxResourceIterable<BoxItem.Info>( 303 api, url, queryBody.getLimit(), queryBody.toJsonObject(), queryBody.getMarker() 304 ) { 305 306 @Override 307 protected BoxItem.Info factory(JsonObject jsonObject) { 308 String type = jsonObject.get("type").asString(); 309 String id = jsonObject.get("id").asString(); 310 311 BoxItem.Info nextItemInfo; 312 switch (type) { 313 case "folder": 314 BoxFolder folder = new BoxFolder(api, id); 315 nextItemInfo = folder.new Info(jsonObject); 316 break; 317 case "file": 318 BoxFile file = new BoxFile(api, id); 319 nextItemInfo = file.new Info(jsonObject); 320 break; 321 case "web_link": 322 BoxWebLink link = new BoxWebLink(api, id); 323 nextItemInfo = link.new Info(jsonObject); 324 break; 325 default: 326 assert false : "Unsupported item type: " + type; 327 throw new BoxAPIException("Unsupported item type: " + type); 328 } 329 330 return nextItemInfo; 331 } 332 }; 333 } 334 335 /** 336 * Gets the JsonObject representation of the Field Operation. 337 * 338 * @param fieldOperation represents the template update operation 339 * @return the json object 340 */ 341 private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperation) { 342 JsonObject jsonObject = new JsonObject(); 343 jsonObject.add("op", fieldOperation.getOp().toString()); 344 345 String fieldKey = fieldOperation.getFieldKey(); 346 if (fieldKey != null) { 347 jsonObject.add("fieldKey", fieldKey); 348 } 349 350 Field field = fieldOperation.getData(); 351 if (field != null) { 352 JsonObject fieldObj = new JsonObject(); 353 354 String type = field.getType(); 355 if (type != null) { 356 fieldObj.add("type", type); 357 } 358 359 String key = field.getKey(); 360 if (key != null) { 361 fieldObj.add("key", key); 362 } 363 364 String displayName = field.getDisplayName(); 365 if (displayName != null) { 366 fieldObj.add("displayName", displayName); 367 } 368 369 String description = field.getDescription(); 370 if (description != null) { 371 fieldObj.add("description", description); 372 } 373 374 Boolean hidden = field.getIsHidden(); 375 if (hidden != null) { 376 fieldObj.add("hidden", hidden); 377 } 378 379 List<String> options = field.getOptions(); 380 if (options != null) { 381 JsonArray array = new JsonArray(); 382 for (String option : options) { 383 JsonObject optionObj = new JsonObject(); 384 optionObj.add("key", option); 385 386 array.add(optionObj); 387 } 388 389 fieldObj.add("options", array); 390 } 391 392 Boolean copyInstanceOnItemCopy = field.getCopyInstanceOnItemCopy(); 393 if (copyInstanceOnItemCopy != null) { 394 fieldObj.add("copyInstanceOnItemCopy", copyInstanceOnItemCopy); 395 } 396 397 jsonObject.add("data", fieldObj); 398 } 399 400 List<String> fieldKeys = fieldOperation.getFieldKeys(); 401 if (fieldKeys != null) { 402 jsonObject.add("fieldKeys", getJsonArray(fieldKeys)); 403 } 404 405 List<String> enumOptionKeys = fieldOperation.getEnumOptionKeys(); 406 if (enumOptionKeys != null) { 407 jsonObject.add("enumOptionKeys", getJsonArray(enumOptionKeys)); 408 } 409 410 String enumOptionKey = fieldOperation.getEnumOptionKey(); 411 if (enumOptionKey != null) { 412 jsonObject.add("enumOptionKey", enumOptionKey); 413 } 414 415 String multiSelectOptionKey = fieldOperation.getMultiSelectOptionKey(); 416 if (multiSelectOptionKey != null) { 417 jsonObject.add("multiSelectOptionKey", multiSelectOptionKey); 418 } 419 420 List<String> multiSelectOptionKeys = fieldOperation.getMultiSelectOptionKeys(); 421 if (multiSelectOptionKeys != null) { 422 jsonObject.add("multiSelectOptionKeys", getJsonArray(multiSelectOptionKeys)); 423 } 424 425 return jsonObject; 426 } 427 428 /** 429 * Gets the Json Array representation of the given list of strings. 430 * 431 * @param keys List of strings 432 * @return the JsonArray represents the list of keys 433 */ 434 private static JsonArray getJsonArray(List<String> keys) { 435 JsonArray array = new JsonArray(); 436 for (String key : keys) { 437 array.add(key); 438 } 439 440 return array; 441 } 442 443 /** 444 * Gets the metadata template of properties. 445 * 446 * @param api the API connection to be used. 447 * @return the metadata template returned from the server. 448 */ 449 public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api) { 450 return getMetadataTemplate(api, DEFAULT_METADATA_TYPE); 451 } 452 453 /** 454 * Gets the metadata template of specified template type. 455 * 456 * @param api the API connection to be used. 457 * @param templateName the metadata template type name. 458 * @return the metadata template returned from the server. 459 */ 460 public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api, String templateName) { 461 String scope = scopeBasedOnType(templateName); 462 return getMetadataTemplate(api, templateName, scope); 463 } 464 465 /** 466 * Gets the metadata template of specified template type. 467 * 468 * @param api the API connection to be used. 469 * @param templateName the metadata template type name. 470 * @param scope the metadata template scope (global or enterprise). 471 * @param fields the fields to retrieve. 472 * @return the metadata template returned from the server. 473 */ 474 public static MetadataTemplate getMetadataTemplate( 475 BoxAPIConnection api, String templateName, String scope, String... fields) { 476 QueryStringBuilder builder = new QueryStringBuilder(); 477 if (fields.length > 0) { 478 builder.appendParam("fields", fields); 479 } 480 URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlphaWithQuery( 481 api.getBaseURL(), builder.toString(), scope, templateName); 482 BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); 483 try (BoxJSONResponse response = request.send()) { 484 return new MetadataTemplate(response.getJSON()); 485 } 486 } 487 488 /** 489 * Geta the specified metadata template by its ID. 490 * 491 * @param api the API connection to be used. 492 * @param templateID the ID of the template to get. 493 * @return the metadata template object. 494 */ 495 public static MetadataTemplate getMetadataTemplateByID(BoxAPIConnection api, String templateID) { 496 497 URL url = METADATA_TEMPLATE_BY_ID_URL_TEMPLATE.buildAlpha(api.getBaseURL(), templateID); 498 BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); 499 try (BoxJSONResponse response = request.send()) { 500 return new MetadataTemplate(response.getJSON()); 501 } 502 } 503 504 /** 505 * Returns all metadata templates within a user's enterprise. 506 * 507 * @param api the API connection to be used. 508 * @param fields the fields to retrieve. 509 * @return the metadata template returned from the server. 510 */ 511 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates(BoxAPIConnection api, String... fields) { 512 return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, api, fields); 513 } 514 515 /** 516 * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported. 517 * 518 * @param scope the scope of the metadata templates. 519 * @param api the API connection to be used. 520 * @param fields the fields to retrieve. 521 * @return the metadata template returned from the server. 522 */ 523 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates( 524 String scope, BoxAPIConnection api, String... fields 525 ) { 526 return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, DEFAULT_ENTRIES_LIMIT, api, fields); 527 } 528 529 /** 530 * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported. 531 * 532 * @param scope the scope of the metadata templates. 533 * @param limit maximum number of entries per response. 534 * @param api the API connection to be used. 535 * @param fields the fields to retrieve. 536 * @return the metadata template returned from the server. 537 */ 538 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates( 539 String scope, int limit, BoxAPIConnection api, String... fields) { 540 QueryStringBuilder builder = new QueryStringBuilder(); 541 if (fields.length > 0) { 542 builder.appendParam("fields", fields); 543 } 544 return new BoxResourceIterable<MetadataTemplate>( 545 api, ENTERPRISE_METADATA_URL_TEMPLATE.buildAlphaWithQuery( 546 api.getBaseURL(), builder.toString(), scope), limit) { 547 548 @Override 549 protected MetadataTemplate factory(JsonObject jsonObject) { 550 return new MetadataTemplate(jsonObject); 551 } 552 }; 553 } 554 555 /** 556 * Determines the metadata scope based on type. 557 * 558 * @param typeName type of the metadata. 559 * @return scope of the metadata. 560 */ 561 private static String scopeBasedOnType(String typeName) { 562 return typeName.equals(DEFAULT_METADATA_TYPE) ? GLOBAL_METADATA_SCOPE : ENTERPRISE_METADATA_SCOPE; 563 } 564 565 /** 566 * Gets the ID of the template. 567 * 568 * @return the template ID. 569 */ 570 public String getID() { 571 return this.id; 572 } 573 574 /** 575 * Gets the unique template key to identify the metadata template. 576 * 577 * @return the unique template key to identify the metadata template. 578 */ 579 public String getTemplateKey() { 580 return this.templateKey; 581 } 582 583 /** 584 * Gets the metadata template scope. 585 * 586 * @return the metadata template scope. 587 */ 588 public String getScope() { 589 return this.scope; 590 } 591 592 /** 593 * Gets the displayed metadata template name. 594 * 595 * @return the displayed metadata template name. 596 */ 597 public String getDisplayName() { 598 return this.displayName; 599 } 600 601 /** 602 * Gets is the metadata template hidden. 603 * 604 * @return is the metadata template hidden. 605 */ 606 public Boolean getIsHidden() { 607 return this.isHidden; 608 } 609 610 /** 611 * Gets the iterable with all fields the metadata template contains. 612 * 613 * @return the iterable with all fields the metadata template contains. 614 */ 615 public List<Field> getFields() { 616 return this.fields; 617 } 618 619 /** 620 * Gets whether the copy operation should copy the metadata along with the item. 621 * 622 * @return whether the copy operation should copy the metadata along with the item. 623 */ 624 public Boolean getCopyInstanceOnItemCopy() { 625 return this.copyInstanceOnItemCopy; 626 } 627 628 /** 629 * {@inheritDoc} 630 */ 631 @Override 632 void parseJSONMember(JsonObject.Member member) { 633 JsonValue value = member.getValue(); 634 String memberName = member.getName(); 635 switch (memberName) { 636 case "templateKey": 637 this.templateKey = value.asString(); 638 break; 639 case "scope": 640 this.scope = value.asString(); 641 break; 642 case "displayName": 643 this.displayName = value.asString(); 644 break; 645 case "hidden": 646 this.isHidden = value.asBoolean(); 647 break; 648 case "fields": 649 this.fields = new ArrayList<>(); 650 for (JsonValue field : value.asArray()) { 651 this.fields.add(new Field(field.asObject())); 652 } 653 break; 654 case "id": 655 this.id = value.asString(); 656 break; 657 case "copyInstanceOnItemCopy": 658 this.copyInstanceOnItemCopy = value.asBoolean(); 659 break; 660 default: 661 break; 662 } 663 } 664 665 /** 666 * Possible template operations. 667 */ 668 public enum Operation { 669 670 /** 671 * Adds an enum option at the end of the enum option list for the specified field. 672 */ 673 addEnumOption, 674 675 /** 676 * Edits the enum option. 677 */ 678 editEnumOption, 679 680 /** 681 * Removes the specified enum option from the specified enum field. 682 */ 683 removeEnumOption, 684 685 /** 686 * Adds a field at the end of the field list for the template. 687 */ 688 addField, 689 690 /** 691 * Edits any number of the base properties of a field: displayName, hidden, description. 692 */ 693 editField, 694 695 /** 696 * Removes the specified field from the template. 697 */ 698 removeField, 699 700 /** 701 * Edits any number of the base properties of a template: displayName, hidden. 702 */ 703 editTemplate, 704 705 /** 706 * Reorders the enum option list to match the requested enum option list. 707 */ 708 reorderEnumOptions, 709 710 /** 711 * Reorders the field list to match the requested field list. 712 */ 713 reorderFields, 714 715 /** 716 * Adds a new option to a multiselect field. 717 */ 718 addMultiSelectOption, 719 720 /** 721 * Edits an existing option in a multiselect field. 722 */ 723 editMultiSelectOption, 724 725 /** 726 * Removes an option from a multiselect field. 727 */ 728 removeMultiSelectOption, 729 730 /** 731 * Changes the display order of options in a multiselect field. 732 */ 733 reorderMultiSelectOptions 734 } 735 736 /** 737 * Class contains information about the metadata template field. 738 */ 739 public static class Field extends BoxJSONObject { 740 741 /** 742 * @see #getID() 743 */ 744 private String id; 745 746 /** 747 * @see #getType() 748 */ 749 private String type; 750 751 /** 752 * @see #getKey() 753 */ 754 private String key; 755 756 /** 757 * @see #getDisplayName() 758 */ 759 private String displayName; 760 761 /** 762 * @see #getIsHidden() 763 */ 764 private Boolean isHidden; 765 766 /** 767 * @see #getDescription() 768 */ 769 private String description; 770 771 /** 772 * @see #getOptionsObjects() 773 */ 774 private List<Option> options; 775 776 /** 777 * @see #getCopyInstanceOnItemCopy() 778 */ 779 private Boolean copyInstanceOnItemCopy; 780 781 /** 782 * Constructs an empty metadata template. 783 */ 784 public Field() { 785 super(); 786 } 787 788 /** 789 * Constructs a metadate template field from a JSON string. 790 * 791 * @param json the json encoded metadate template field. 792 */ 793 public Field(String json) { 794 super(json); 795 } 796 797 /** 798 * Constructs a metadate template field from a JSON object. 799 * 800 * @param jsonObject the json encoded metadate template field. 801 */ 802 Field(JsonObject jsonObject) { 803 super(jsonObject); 804 } 805 806 /** 807 * Gets the ID of the template field. 808 * 809 * @return the template field ID. 810 */ 811 public String getID() { 812 return this.id; 813 } 814 815 /** 816 * Gets the data type of the field's value. 817 * 818 * @return the data type of the field's value. 819 */ 820 public String getType() { 821 return this.type; 822 } 823 824 /** 825 * Sets the data type of the field's value. 826 * 827 * @param type the data type of the field's value. 828 */ 829 public void setType(String type) { 830 this.type = type; 831 } 832 833 /** 834 * Gets the key of the field. 835 * 836 * @return the key of the field. 837 */ 838 public String getKey() { 839 return this.key; 840 } 841 842 /** 843 * Sets the key of the field. 844 * 845 * @param key the key of the field. 846 */ 847 public void setKey(String key) { 848 this.key = key; 849 } 850 851 /** 852 * Gets the display name of the field. 853 * 854 * @return the display name of the field. 855 */ 856 public String getDisplayName() { 857 return this.displayName; 858 } 859 860 /** 861 * Sets the display name of the field. 862 * 863 * @param displayName the display name of the field. 864 */ 865 public void setDisplayName(String displayName) { 866 this.displayName = displayName; 867 } 868 869 /** 870 * Gets is metadata template field hidden. 871 * 872 * @return is metadata template field hidden. 873 */ 874 public Boolean getIsHidden() { 875 return this.isHidden; 876 } 877 878 /** 879 * Sets is metadata template field hidden. 880 * 881 * @param isHidden is metadata template field hidden? 882 */ 883 public void setIsHidden(boolean isHidden) { 884 this.isHidden = isHidden; 885 } 886 887 /** 888 * Gets the description of the field. 889 * 890 * @return the description of the field. 891 */ 892 public String getDescription() { 893 return this.description; 894 } 895 896 /** 897 * Sets the description of the field. 898 * 899 * @param description the description of the field. 900 */ 901 public void setDescription(String description) { 902 this.description = description; 903 } 904 905 /** 906 * Gets list of possible options for enum type of the field. 907 * 908 * @return list of possible options for enum type of the field. 909 */ 910 public List<String> getOptions() { 911 if (this.options == null) { 912 return null; 913 } 914 List<String> optionsList = new ArrayList<>(); 915 for (Option option : this.options) { 916 optionsList.add(option.getKey()); 917 } 918 return optionsList; 919 } 920 921 /** 922 * Sets list of possible options for enum type of the field. 923 * 924 * @param options list of possible options for enum type of the field. 925 */ 926 public void setOptions(List<String> options) { 927 if (options == null) { 928 this.options = null; 929 return; 930 } 931 List<Option> optionList = new ArrayList<>(); 932 for (String key : options) { 933 JsonObject optionObject = new JsonObject(); 934 optionObject.add("key", key); 935 Option newOption = new Option(optionObject); 936 optionList.add(newOption); 937 } 938 this.options = optionList; 939 } 940 941 /** 942 * Gets list of possible options for options type of the field. 943 * 944 * @return list of possible options for option type of the field. 945 */ 946 public List<Option> getOptionsObjects() { 947 return this.options; 948 } 949 950 /** 951 * Gets whether the copy operation should copy the metadata along with the item. 952 * 953 * @return whether the copy operation should copy the metadata along with the item. 954 */ 955 public Boolean getCopyInstanceOnItemCopy() { 956 return this.copyInstanceOnItemCopy; 957 } 958 959 /** 960 * Sets whether the copy operation should copy the metadata along with the item. 961 * 962 * @param copyInstanceOnItemCopy whether the copy operation should copy the metadata along with the item. 963 */ 964 public void setCopyInstanceOnItemCopy(Boolean copyInstanceOnItemCopy) { 965 this.copyInstanceOnItemCopy = copyInstanceOnItemCopy; 966 } 967 968 /** 969 * {@inheritDoc} 970 */ 971 @Override 972 void parseJSONMember(JsonObject.Member member) { 973 JsonValue value = member.getValue(); 974 String memberName = member.getName(); 975 switch (memberName) { 976 case "type": 977 this.type = value.asString(); 978 break; 979 case "key": 980 this.key = value.asString(); 981 break; 982 case "displayName": 983 this.displayName = value.asString(); 984 break; 985 case "hidden": 986 this.isHidden = value.asBoolean(); 987 break; 988 case "description": 989 this.description = value.asString(); 990 break; 991 case "options": 992 this.options = new ArrayList<>(); 993 for (JsonValue option : value.asArray()) { 994 this.options.add(new Option(option.asObject())); 995 } 996 break; 997 case "id": 998 this.id = value.asString(); 999 break; 1000 case "copyInstanceOnItemCopy": 1001 this.copyInstanceOnItemCopy = value.asBoolean(); 1002 break; 1003 default: 1004 break; 1005 } 1006 } 1007 } 1008 1009 /** 1010 * Class contains information about the metadata template option. 1011 */ 1012 public static class Option extends BoxJSONObject { 1013 /** 1014 * @see #getID() 1015 */ 1016 private String id; 1017 /** 1018 * @see #getKey() 1019 */ 1020 private String key; 1021 1022 /** 1023 * Constructs an empty metadata template. 1024 */ 1025 public Option() { 1026 super(); 1027 } 1028 1029 /** 1030 * Constructs a metadate template option from a JSON string. 1031 * 1032 * @param json the json encoded metadata template option. 1033 */ 1034 public Option(String json) { 1035 super(json); 1036 } 1037 1038 /** 1039 * Constructs a metadate template option from a JSON object. 1040 * 1041 * @param jsonObject the json encoded metadate template option. 1042 */ 1043 Option(JsonObject jsonObject) { 1044 super(jsonObject); 1045 } 1046 1047 /** 1048 * Gets the ID of the template field. 1049 * 1050 * @return the template field ID. 1051 */ 1052 public String getID() { 1053 return this.id; 1054 } 1055 1056 /** 1057 * Gets the key of the field. 1058 * 1059 * @return the key of the field. 1060 */ 1061 public String getKey() { 1062 return this.key; 1063 } 1064 1065 /** 1066 * {@inheritDoc} 1067 */ 1068 @Override 1069 void parseJSONMember(JsonObject.Member member) { 1070 JsonValue value = member.getValue(); 1071 String memberName = member.getName(); 1072 if (memberName.equals("id")) { 1073 this.id = value.asString(); 1074 } else if (memberName.equals("key")) { 1075 this.key = value.asString(); 1076 } 1077 } 1078 } 1079 1080 /** 1081 * Posssible operations that can be performed in a Metadata template. 1082 * <ul> 1083 * <li>Add an enum option</li> 1084 * <li>Edit an enum option</li> 1085 * <li>Remove an enum option</li> 1086 * <li>Add a field</li> 1087 * <li>Edit a field</li> 1088 * <li>Remove a field</li> 1089 * <li>Edit template</li> 1090 * <li>Reorder the enum option</li> 1091 * <li>Reorder the field list</li> 1092 * </ul> 1093 */ 1094 public static class FieldOperation extends BoxJSONObject { 1095 1096 private Operation op; 1097 private Field data; 1098 private String fieldKey; 1099 private List<String> fieldKeys; 1100 private List<String> enumOptionKeys; 1101 private String enumOptionKey; 1102 private String multiSelectOptionKey; 1103 private List<String> multiSelectOptionKeys; 1104 1105 /** 1106 * Constructs an empty FieldOperation. 1107 */ 1108 public FieldOperation() { 1109 super(); 1110 } 1111 1112 /** 1113 * Constructs a Field operation from a JSON string. 1114 * 1115 * @param json the json encoded metadate template field. 1116 */ 1117 public FieldOperation(String json) { 1118 super(json); 1119 } 1120 1121 /** 1122 * Constructs a Field operation from a JSON object. 1123 * 1124 * @param jsonObject the json encoded metadate template field. 1125 */ 1126 FieldOperation(JsonObject jsonObject) { 1127 super(jsonObject); 1128 } 1129 1130 /** 1131 * Gets the operation. 1132 * 1133 * @return the operation 1134 */ 1135 public Operation getOp() { 1136 return this.op; 1137 } 1138 1139 /** 1140 * Sets the operation. 1141 * 1142 * @param op the operation 1143 */ 1144 public void setOp(Operation op) { 1145 this.op = op; 1146 } 1147 1148 /** 1149 * Gets the data associated with the operation. 1150 * 1151 * @return the field object representing the data 1152 */ 1153 public Field getData() { 1154 return this.data; 1155 } 1156 1157 /** 1158 * Sets the data. 1159 * 1160 * @param data the Field object representing the data 1161 */ 1162 public void setData(Field data) { 1163 this.data = data; 1164 } 1165 1166 /** 1167 * Gets the field key. 1168 * 1169 * @return the field key 1170 */ 1171 public String getFieldKey() { 1172 return this.fieldKey; 1173 } 1174 1175 /** 1176 * Sets the field key. 1177 * 1178 * @param fieldKey the key of the field 1179 */ 1180 public void setFieldKey(String fieldKey) { 1181 this.fieldKey = fieldKey; 1182 } 1183 1184 /** 1185 * Gets the list of field keys. 1186 * 1187 * @return the list of Strings 1188 */ 1189 public List<String> getFieldKeys() { 1190 return this.fieldKeys; 1191 } 1192 1193 /** 1194 * Sets the list of the field keys. 1195 * 1196 * @param fieldKeys the list of strings 1197 */ 1198 public void setFieldKeys(List<String> fieldKeys) { 1199 this.fieldKeys = fieldKeys; 1200 } 1201 1202 /** 1203 * Gets the list of keys of the Enum options. 1204 * 1205 * @return the list of Strings 1206 */ 1207 public List<String> getEnumOptionKeys() { 1208 return this.enumOptionKeys; 1209 } 1210 1211 /** 1212 * Sets the list of the enum option keys. 1213 * 1214 * @param enumOptionKeys the list of Strings 1215 */ 1216 public void setEnumOptionKeys(List<String> enumOptionKeys) { 1217 this.enumOptionKeys = enumOptionKeys; 1218 } 1219 1220 /** 1221 * Gets the enum option key. 1222 * 1223 * @return the enum option key 1224 */ 1225 public String getEnumOptionKey() { 1226 return this.enumOptionKey; 1227 } 1228 1229 /** 1230 * Sets the enum option key. 1231 * 1232 * @param enumOptionKey the enum option key 1233 */ 1234 public void setEnumOptionKey(String enumOptionKey) { 1235 this.enumOptionKey = enumOptionKey; 1236 } 1237 1238 /** 1239 * Gets the multi-select option key. 1240 * 1241 * @return the key. 1242 */ 1243 public String getMultiSelectOptionKey() { 1244 return this.multiSelectOptionKey; 1245 } 1246 1247 /** 1248 * Sets the multi-select option key. 1249 * 1250 * @param key the key. 1251 */ 1252 public void setMultiSelectOptionKey(String key) { 1253 this.multiSelectOptionKey = key; 1254 } 1255 1256 /** 1257 * Gets the list of multiselect option keys. 1258 * 1259 * @return the list of keys. 1260 */ 1261 public List<String> getMultiSelectOptionKeys() { 1262 return this.multiSelectOptionKeys; 1263 } 1264 1265 /** 1266 * Sets the multi-select option keys. 1267 * 1268 * @param keys the list of keys. 1269 */ 1270 public void setMultiSelectOptionKeys(List<String> keys) { 1271 this.multiSelectOptionKeys = keys; 1272 } 1273 1274 @Override 1275 public void clearPendingChanges() { 1276 super.clearPendingChanges(); 1277 } 1278 1279 /** 1280 * {@inheritDoc} 1281 */ 1282 @Override 1283 void parseJSONMember(JsonObject.Member member) { 1284 JsonValue value = member.getValue(); 1285 String memberName = member.getName(); 1286 switch (memberName) { 1287 case "op": 1288 this.op = Operation.valueOf(value.asString()); 1289 break; 1290 case "data": 1291 this.data = new Field(value.asObject()); 1292 break; 1293 case "fieldKey": 1294 this.fieldKey = value.asString(); 1295 break; 1296 case "fieldKeys": 1297 if (this.fieldKeys == null) { 1298 this.fieldKeys = new ArrayList<>(); 1299 } else { 1300 this.fieldKeys.clear(); 1301 } 1302 for (JsonValue jsonValue : value.asArray()) { 1303 this.fieldKeys.add(jsonValue.asString()); 1304 } 1305 break; 1306 case "enumOptionKeys": 1307 if (this.enumOptionKeys == null) { 1308 this.enumOptionKeys = new ArrayList<>(); 1309 } else { 1310 this.enumOptionKeys.clear(); 1311 } 1312 1313 for (JsonValue jsonValue : value.asArray()) { 1314 this.enumOptionKeys.add(jsonValue.asString()); 1315 } 1316 break; 1317 case "enumOptionKey": 1318 this.enumOptionKey = value.asString(); 1319 break; 1320 case "multiSelectOptionKey": 1321 this.multiSelectOptionKey = value.asString(); 1322 break; 1323 case "multiSelectOptionKeys": 1324 this.multiSelectOptionKeys = new ArrayList<>(); 1325 for (JsonValue key : value.asArray()) { 1326 this.multiSelectOptionKeys.add(key.asString()); 1327 } 1328 break; 1329 default: 1330 break; 1331 } 1332 } 1333 } 1334}