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 StaticConfig staticConfig = field.getStaticConfig(); 398 if (staticConfig != null) { 399 JsonObject staticConfigObj = new JsonObject(); 400 JsonObject classification = staticConfig.getClassification(); 401 if (classification != null) { 402 staticConfigObj.add("classification", classification); 403 } 404 fieldObj.add("staticConfig", staticConfigObj); 405 } 406 407 jsonObject.add("data", fieldObj); 408 } 409 410 List<String> fieldKeys = fieldOperation.getFieldKeys(); 411 if (fieldKeys != null) { 412 jsonObject.add("fieldKeys", getJsonArray(fieldKeys)); 413 } 414 415 List<String> enumOptionKeys = fieldOperation.getEnumOptionKeys(); 416 if (enumOptionKeys != null) { 417 jsonObject.add("enumOptionKeys", getJsonArray(enumOptionKeys)); 418 } 419 420 String enumOptionKey = fieldOperation.getEnumOptionKey(); 421 if (enumOptionKey != null) { 422 jsonObject.add("enumOptionKey", enumOptionKey); 423 } 424 425 String multiSelectOptionKey = fieldOperation.getMultiSelectOptionKey(); 426 if (multiSelectOptionKey != null) { 427 jsonObject.add("multiSelectOptionKey", multiSelectOptionKey); 428 } 429 430 List<String> multiSelectOptionKeys = fieldOperation.getMultiSelectOptionKeys(); 431 if (multiSelectOptionKeys != null) { 432 jsonObject.add("multiSelectOptionKeys", getJsonArray(multiSelectOptionKeys)); 433 } 434 435 return jsonObject; 436 } 437 438 /** 439 * Gets the Json Array representation of the given list of strings. 440 * 441 * @param keys List of strings 442 * @return the JsonArray represents the list of keys 443 */ 444 private static JsonArray getJsonArray(List<String> keys) { 445 JsonArray array = new JsonArray(); 446 for (String key : keys) { 447 array.add(key); 448 } 449 450 return array; 451 } 452 453 /** 454 * Gets the metadata template of properties. 455 * 456 * @param api the API connection to be used. 457 * @return the metadata template returned from the server. 458 */ 459 public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api) { 460 return getMetadataTemplate(api, DEFAULT_METADATA_TYPE); 461 } 462 463 /** 464 * Gets the metadata template of specified template type. 465 * 466 * @param api the API connection to be used. 467 * @param templateName the metadata template type name. 468 * @return the metadata template returned from the server. 469 */ 470 public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api, String templateName) { 471 String scope = scopeBasedOnType(templateName); 472 return getMetadataTemplate(api, templateName, scope); 473 } 474 475 /** 476 * Gets the metadata template of specified template type. 477 * 478 * @param api the API connection to be used. 479 * @param templateName the metadata template type name. 480 * @param scope the metadata template scope (global or enterprise). 481 * @param fields the fields to retrieve. 482 * @return the metadata template returned from the server. 483 */ 484 public static MetadataTemplate getMetadataTemplate( 485 BoxAPIConnection api, String templateName, String scope, String... fields) { 486 QueryStringBuilder builder = new QueryStringBuilder(); 487 if (fields.length > 0) { 488 builder.appendParam("fields", fields); 489 } 490 URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlphaWithQuery( 491 api.getBaseURL(), builder.toString(), scope, templateName); 492 BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); 493 try (BoxJSONResponse response = request.send()) { 494 return new MetadataTemplate(response.getJSON()); 495 } 496 } 497 498 /** 499 * Geta the specified metadata template by its ID. 500 * 501 * @param api the API connection to be used. 502 * @param templateID the ID of the template to get. 503 * @return the metadata template object. 504 */ 505 public static MetadataTemplate getMetadataTemplateByID(BoxAPIConnection api, String templateID) { 506 507 URL url = METADATA_TEMPLATE_BY_ID_URL_TEMPLATE.buildAlpha(api.getBaseURL(), templateID); 508 BoxJSONRequest request = new BoxJSONRequest(api, url, "GET"); 509 try (BoxJSONResponse response = request.send()) { 510 return new MetadataTemplate(response.getJSON()); 511 } 512 } 513 514 /** 515 * Returns all metadata templates within a user's enterprise. 516 * 517 * @param api the API connection to be used. 518 * @param fields the fields to retrieve. 519 * @return the metadata template returned from the server. 520 */ 521 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates(BoxAPIConnection api, String... fields) { 522 return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, api, fields); 523 } 524 525 /** 526 * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported. 527 * 528 * @param scope the scope of the metadata templates. 529 * @param api the API connection to be used. 530 * @param fields the fields to retrieve. 531 * @return the metadata template returned from the server. 532 */ 533 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates( 534 String scope, BoxAPIConnection api, String... fields 535 ) { 536 return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, DEFAULT_ENTRIES_LIMIT, api, fields); 537 } 538 539 /** 540 * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported. 541 * 542 * @param scope the scope of the metadata templates. 543 * @param limit maximum number of entries per response. 544 * @param api the API connection to be used. 545 * @param fields the fields to retrieve. 546 * @return the metadata template returned from the server. 547 */ 548 public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates( 549 String scope, int limit, BoxAPIConnection api, String... fields) { 550 QueryStringBuilder builder = new QueryStringBuilder(); 551 if (fields.length > 0) { 552 builder.appendParam("fields", fields); 553 } 554 return new BoxResourceIterable<MetadataTemplate>( 555 api, ENTERPRISE_METADATA_URL_TEMPLATE.buildAlphaWithQuery( 556 api.getBaseURL(), builder.toString(), scope), limit) { 557 558 @Override 559 protected MetadataTemplate factory(JsonObject jsonObject) { 560 return new MetadataTemplate(jsonObject); 561 } 562 }; 563 } 564 565 /** 566 * Determines the metadata scope based on type. 567 * 568 * @param typeName type of the metadata. 569 * @return scope of the metadata. 570 */ 571 private static String scopeBasedOnType(String typeName) { 572 return typeName.equals(DEFAULT_METADATA_TYPE) ? GLOBAL_METADATA_SCOPE : ENTERPRISE_METADATA_SCOPE; 573 } 574 575 /** 576 * Gets the ID of the template. 577 * 578 * @return the template ID. 579 */ 580 public String getID() { 581 return this.id; 582 } 583 584 /** 585 * Gets the unique template key to identify the metadata template. 586 * 587 * @return the unique template key to identify the metadata template. 588 */ 589 public String getTemplateKey() { 590 return this.templateKey; 591 } 592 593 /** 594 * Gets the metadata template scope. 595 * 596 * @return the metadata template scope. 597 */ 598 public String getScope() { 599 return this.scope; 600 } 601 602 /** 603 * Gets the displayed metadata template name. 604 * 605 * @return the displayed metadata template name. 606 */ 607 public String getDisplayName() { 608 return this.displayName; 609 } 610 611 /** 612 * Gets is the metadata template hidden. 613 * 614 * @return is the metadata template hidden. 615 */ 616 public Boolean getIsHidden() { 617 return this.isHidden; 618 } 619 620 /** 621 * Gets the iterable with all fields the metadata template contains. 622 * 623 * @return the iterable with all fields the metadata template contains. 624 */ 625 public List<Field> getFields() { 626 return this.fields; 627 } 628 629 /** 630 * Gets whether the copy operation should copy the metadata along with the item. 631 * 632 * @return whether the copy operation should copy the metadata along with the item. 633 */ 634 public Boolean getCopyInstanceOnItemCopy() { 635 return this.copyInstanceOnItemCopy; 636 } 637 638 /** 639 * {@inheritDoc} 640 */ 641 @Override 642 void parseJSONMember(JsonObject.Member member) { 643 JsonValue value = member.getValue(); 644 String memberName = member.getName(); 645 switch (memberName) { 646 case "templateKey": 647 this.templateKey = value.asString(); 648 break; 649 case "scope": 650 this.scope = value.asString(); 651 break; 652 case "displayName": 653 this.displayName = value.asString(); 654 break; 655 case "hidden": 656 this.isHidden = value.asBoolean(); 657 break; 658 case "fields": 659 this.fields = new ArrayList<>(); 660 for (JsonValue field : value.asArray()) { 661 this.fields.add(new Field(field.asObject())); 662 } 663 break; 664 case "id": 665 this.id = value.asString(); 666 break; 667 case "copyInstanceOnItemCopy": 668 this.copyInstanceOnItemCopy = value.asBoolean(); 669 break; 670 default: 671 break; 672 } 673 } 674 675 /** 676 * Possible template operations. 677 */ 678 public enum Operation { 679 680 /** 681 * Adds an enum option at the end of the enum option list for the specified field. 682 */ 683 addEnumOption, 684 685 /** 686 * Edits the enum option. 687 */ 688 editEnumOption, 689 690 /** 691 * Removes the specified enum option from the specified enum field. 692 */ 693 removeEnumOption, 694 695 /** 696 * Adds a field at the end of the field list for the template. 697 */ 698 addField, 699 700 /** 701 * Edits any number of the base properties of a field: displayName, hidden, description. 702 */ 703 editField, 704 705 /** 706 * Removes the specified field from the template. 707 */ 708 removeField, 709 710 /** 711 * Edits any number of the base properties of a template: displayName, hidden. 712 */ 713 editTemplate, 714 715 /** 716 * Reorders the enum option list to match the requested enum option list. 717 */ 718 reorderEnumOptions, 719 720 /** 721 * Reorders the field list to match the requested field list. 722 */ 723 reorderFields, 724 725 /** 726 * Adds a new option to a multiselect field. 727 */ 728 addMultiSelectOption, 729 730 /** 731 * Edits an existing option in a multiselect field. 732 */ 733 editMultiSelectOption, 734 735 /** 736 * Removes an option from a multiselect field. 737 */ 738 removeMultiSelectOption, 739 740 /** 741 * Changes the display order of options in a multiselect field. 742 */ 743 reorderMultiSelectOptions 744 } 745 746 /** 747 * Class contains information about the static configuration for the classification. 748 */ 749 public static class StaticConfig extends BoxJSONObject { 750 private JsonObject classification; 751 752 /** 753 * Constructs an empty static configuration. 754 */ 755 public StaticConfig() { 756 super(); 757 } 758 759 /** 760 * Constructs a static configuration from a JSON string. 761 * 762 * @param json the json encoded metadate template field. 763 */ 764 public StaticConfig(String json) { 765 super(json); 766 } 767 768 /** Constructs a static configuration from a JSON object. 769 * 770 * @param jsonObject the json encoded metadate template field. 771 */ 772 StaticConfig(JsonObject jsonObject) { 773 super(jsonObject); 774 } 775 776 /** 777 * Gets the classification of the static configuration. 778 * 779 * @return the classification of the static configuration. 780 */ 781 public JsonObject getClassification() { 782 return this.classification; 783 } 784 785 /** 786 * Sets the classification of the static configuration. 787 * 788 * @param classification the classification of the static configuration. 789 */ 790 public void setClassification(JsonObject classification) { 791 this.classification = classification; 792 } 793 794 /** 795 * {@inheritDoc} 796 */ 797 @Override 798 void parseJSONMember(JsonObject.Member member) { 799 JsonValue value = member.getValue(); 800 String memberName = member.getName(); 801 switch (memberName) { 802 case "classification": 803 this.classification = value.asObject(); 804 break; 805 default: 806 break; 807 } 808 } 809 } 810 811 /** 812 * Class contains information about the metadata template field. 813 */ 814 public static class Field extends BoxJSONObject { 815 816 /** 817 * @see #getID() 818 */ 819 private String id; 820 821 /** 822 * @see #getType() 823 */ 824 private String type; 825 826 /** 827 * @see #getKey() 828 */ 829 private String key; 830 831 /** 832 * @see #getDisplayName() 833 */ 834 private String displayName; 835 836 /** 837 * @see #getIsHidden() 838 */ 839 private Boolean isHidden; 840 841 /** 842 * @see #getDescription() 843 */ 844 private String description; 845 846 /** 847 * @see #getOptionsObjects() 848 */ 849 private List<Option> options; 850 851 /** 852 * @see #getCopyInstanceOnItemCopy() 853 */ 854 private Boolean copyInstanceOnItemCopy; 855 856 /** 857 * @see #getStaticConfig() 858 */ 859 private StaticConfig staticConfig; 860 861 /** 862 * Constructs an empty metadata template. 863 */ 864 public Field() { 865 super(); 866 } 867 868 /** 869 * Constructs a metadate template field from a JSON string. 870 * 871 * @param json the json encoded metadate template field. 872 */ 873 public Field(String json) { 874 super(json); 875 } 876 877 /** 878 * Constructs a metadate template field from a JSON object. 879 * 880 * @param jsonObject the json encoded metadate template field. 881 */ 882 Field(JsonObject jsonObject) { 883 super(jsonObject); 884 } 885 886 /** 887 * Gets the ID of the template field. 888 * 889 * @return the template field ID. 890 */ 891 public String getID() { 892 return this.id; 893 } 894 895 /** 896 * Gets the data type of the field's value. 897 * 898 * @return the data type of the field's value. 899 */ 900 public String getType() { 901 return this.type; 902 } 903 904 /** 905 * Sets the data type of the field's value. 906 * 907 * @param type the data type of the field's value. 908 */ 909 public void setType(String type) { 910 this.type = type; 911 } 912 913 /** 914 * Gets the key of the field. 915 * 916 * @return the key of the field. 917 */ 918 public String getKey() { 919 return this.key; 920 } 921 922 /** 923 * Sets the key of the field. 924 * 925 * @param key the key of the field. 926 */ 927 public void setKey(String key) { 928 this.key = key; 929 } 930 931 /** 932 * Gets the display name of the field. 933 * 934 * @return the display name of the field. 935 */ 936 public String getDisplayName() { 937 return this.displayName; 938 } 939 940 /** 941 * Sets the display name of the field. 942 * 943 * @param displayName the display name of the field. 944 */ 945 public void setDisplayName(String displayName) { 946 this.displayName = displayName; 947 } 948 949 /** 950 * Gets is metadata template field hidden. 951 * 952 * @return is metadata template field hidden. 953 */ 954 public Boolean getIsHidden() { 955 return this.isHidden; 956 } 957 958 /** 959 * Sets is metadata template field hidden. 960 * 961 * @param isHidden is metadata template field hidden? 962 */ 963 public void setIsHidden(boolean isHidden) { 964 this.isHidden = isHidden; 965 } 966 967 /** 968 * Gets the description of the field. 969 * 970 * @return the description of the field. 971 */ 972 public String getDescription() { 973 return this.description; 974 } 975 976 /** 977 * Sets the description of the field. 978 * 979 * @param description the description of the field. 980 */ 981 public void setDescription(String description) { 982 this.description = description; 983 } 984 985 /** 986 * Gets list of possible options for enum type of the field. 987 * 988 * @return list of possible options for enum type of the field. 989 */ 990 public List<String> getOptions() { 991 if (this.options == null) { 992 return null; 993 } 994 List<String> optionsList = new ArrayList<>(); 995 for (Option option : this.options) { 996 optionsList.add(option.getKey()); 997 } 998 return optionsList; 999 } 1000 1001 /** 1002 * Sets list of possible options for enum type of the field. 1003 * 1004 * @param options list of possible options for enum type of the field. 1005 */ 1006 public void setOptions(List<String> options) { 1007 if (options == null) { 1008 this.options = null; 1009 return; 1010 } 1011 List<Option> optionList = new ArrayList<>(); 1012 for (String key : options) { 1013 JsonObject optionObject = new JsonObject(); 1014 optionObject.add("key", key); 1015 Option newOption = new Option(optionObject); 1016 optionList.add(newOption); 1017 } 1018 this.options = optionList; 1019 } 1020 1021 /** 1022 * Gets list of possible options for options type of the field. 1023 * 1024 * @return list of possible options for option type of the field. 1025 */ 1026 public List<Option> getOptionsObjects() { 1027 return this.options; 1028 } 1029 1030 /** 1031 * Gets whether the copy operation should copy the metadata along with the item. 1032 * 1033 * @return whether the copy operation should copy the metadata along with the item. 1034 */ 1035 public Boolean getCopyInstanceOnItemCopy() { 1036 return this.copyInstanceOnItemCopy; 1037 } 1038 1039 /** 1040 * Sets whether the copy operation should copy the metadata along with the item. 1041 * 1042 * @param copyInstanceOnItemCopy whether the copy operation should copy the metadata along with the item. 1043 */ 1044 public void setCopyInstanceOnItemCopy(Boolean copyInstanceOnItemCopy) { 1045 this.copyInstanceOnItemCopy = copyInstanceOnItemCopy; 1046 } 1047 1048 /** 1049 * Gets static configuration for the classification. 1050 * 1051 * @return static configuration for the classification. 1052 */ 1053 public StaticConfig getStaticConfig() { 1054 return this.staticConfig; 1055 } 1056 1057 /** 1058 * Sets static configuration for the classification. 1059 * 1060 * @param staticConfig static configuration for the classification. 1061 */ 1062 public void setStaticConfig(StaticConfig staticConfig) { 1063 this.staticConfig = staticConfig; 1064 } 1065 1066 /** 1067 * {@inheritDoc} 1068 */ 1069 @Override 1070 void parseJSONMember(JsonObject.Member member) { 1071 JsonValue value = member.getValue(); 1072 String memberName = member.getName(); 1073 switch (memberName) { 1074 case "type": 1075 this.type = value.asString(); 1076 break; 1077 case "key": 1078 this.key = value.asString(); 1079 break; 1080 case "displayName": 1081 this.displayName = value.asString(); 1082 break; 1083 case "hidden": 1084 this.isHidden = value.asBoolean(); 1085 break; 1086 case "description": 1087 this.description = value.asString(); 1088 break; 1089 case "options": 1090 this.options = new ArrayList<>(); 1091 for (JsonValue option : value.asArray()) { 1092 this.options.add(new Option(option.asObject())); 1093 } 1094 break; 1095 case "id": 1096 this.id = value.asString(); 1097 break; 1098 case "copyInstanceOnItemCopy": 1099 this.copyInstanceOnItemCopy = value.asBoolean(); 1100 break; 1101 case "staticConfig": 1102 this.staticConfig = new StaticConfig(value.asObject()); 1103 break; 1104 default: 1105 break; 1106 } 1107 } 1108 } 1109 1110 /** 1111 * Class contains information about the metadata template option. 1112 */ 1113 public static class Option extends BoxJSONObject { 1114 /** 1115 * @see #getID() 1116 */ 1117 private String id; 1118 /** 1119 * @see #getKey() 1120 */ 1121 private String key; 1122 /** 1123 * @see #getStaticConfig() 1124 */ 1125 private StaticConfig staticConfig; 1126 1127 /** 1128 * Constructs an empty metadata template. 1129 */ 1130 public Option() { 1131 super(); 1132 } 1133 1134 /** 1135 * Constructs a metadate template option from a JSON string. 1136 * 1137 * @param json the json encoded metadata template option. 1138 */ 1139 public Option(String json) { 1140 super(json); 1141 } 1142 1143 /** 1144 * Constructs a metadate template option from a JSON object. 1145 * 1146 * @param jsonObject the json encoded metadate template option. 1147 */ 1148 Option(JsonObject jsonObject) { 1149 super(jsonObject); 1150 } 1151 1152 /** 1153 * Gets the ID of the template field. 1154 * 1155 * @return the template field ID. 1156 */ 1157 public String getID() { 1158 return this.id; 1159 } 1160 1161 /** 1162 * Gets the key of the field. 1163 * 1164 * @return the key of the field. 1165 */ 1166 public String getKey() { 1167 return this.key; 1168 } 1169 1170 /** 1171 * Gets static configuration for the classification. 1172 * 1173 * @return static configuration for the classification. 1174 */ 1175 public StaticConfig getStaticConfig() { 1176 return this.staticConfig; 1177 } 1178 1179 /** 1180 * {@inheritDoc} 1181 */ 1182 @Override 1183 void parseJSONMember(JsonObject.Member member) { 1184 JsonValue value = member.getValue(); 1185 String memberName = member.getName(); 1186 switch (memberName) { 1187 case "id": 1188 this.id = value.asString(); 1189 break; 1190 case "key": 1191 this.key = value.asString(); 1192 break; 1193 case "staticConfig": 1194 this.staticConfig = new StaticConfig(value.asObject()); 1195 break; 1196 default: 1197 break; 1198 } 1199 } 1200 } 1201 1202 /** 1203 * Posssible operations that can be performed in a Metadata template. 1204 * <ul> 1205 * <li>Add an enum option</li> 1206 * <li>Edit an enum option</li> 1207 * <li>Remove an enum option</li> 1208 * <li>Add a field</li> 1209 * <li>Edit a field</li> 1210 * <li>Remove a field</li> 1211 * <li>Edit template</li> 1212 * <li>Reorder the enum option</li> 1213 * <li>Reorder the field list</li> 1214 * </ul> 1215 */ 1216 public static class FieldOperation extends BoxJSONObject { 1217 1218 private Operation op; 1219 private Field data; 1220 private String fieldKey; 1221 private List<String> fieldKeys; 1222 private List<String> enumOptionKeys; 1223 private String enumOptionKey; 1224 private String multiSelectOptionKey; 1225 private List<String> multiSelectOptionKeys; 1226 1227 /** 1228 * Constructs an empty FieldOperation. 1229 */ 1230 public FieldOperation() { 1231 super(); 1232 } 1233 1234 /** 1235 * Constructs a Field operation from a JSON string. 1236 * 1237 * @param json the json encoded metadate template field. 1238 */ 1239 public FieldOperation(String json) { 1240 super(json); 1241 } 1242 1243 /** 1244 * Constructs a Field operation from a JSON object. 1245 * 1246 * @param jsonObject the json encoded metadate template field. 1247 */ 1248 FieldOperation(JsonObject jsonObject) { 1249 super(jsonObject); 1250 } 1251 1252 /** 1253 * Gets the operation. 1254 * 1255 * @return the operation 1256 */ 1257 public Operation getOp() { 1258 return this.op; 1259 } 1260 1261 /** 1262 * Sets the operation. 1263 * 1264 * @param op the operation 1265 */ 1266 public void setOp(Operation op) { 1267 this.op = op; 1268 } 1269 1270 /** 1271 * Gets the data associated with the operation. 1272 * 1273 * @return the field object representing the data 1274 */ 1275 public Field getData() { 1276 return this.data; 1277 } 1278 1279 /** 1280 * Sets the data. 1281 * 1282 * @param data the Field object representing the data 1283 */ 1284 public void setData(Field data) { 1285 this.data = data; 1286 } 1287 1288 /** 1289 * Gets the field key. 1290 * 1291 * @return the field key 1292 */ 1293 public String getFieldKey() { 1294 return this.fieldKey; 1295 } 1296 1297 /** 1298 * Sets the field key. 1299 * 1300 * @param fieldKey the key of the field 1301 */ 1302 public void setFieldKey(String fieldKey) { 1303 this.fieldKey = fieldKey; 1304 } 1305 1306 /** 1307 * Gets the list of field keys. 1308 * 1309 * @return the list of Strings 1310 */ 1311 public List<String> getFieldKeys() { 1312 return this.fieldKeys; 1313 } 1314 1315 /** 1316 * Sets the list of the field keys. 1317 * 1318 * @param fieldKeys the list of strings 1319 */ 1320 public void setFieldKeys(List<String> fieldKeys) { 1321 this.fieldKeys = fieldKeys; 1322 } 1323 1324 /** 1325 * Gets the list of keys of the Enum options. 1326 * 1327 * @return the list of Strings 1328 */ 1329 public List<String> getEnumOptionKeys() { 1330 return this.enumOptionKeys; 1331 } 1332 1333 /** 1334 * Sets the list of the enum option keys. 1335 * 1336 * @param enumOptionKeys the list of Strings 1337 */ 1338 public void setEnumOptionKeys(List<String> enumOptionKeys) { 1339 this.enumOptionKeys = enumOptionKeys; 1340 } 1341 1342 /** 1343 * Gets the enum option key. 1344 * 1345 * @return the enum option key 1346 */ 1347 public String getEnumOptionKey() { 1348 return this.enumOptionKey; 1349 } 1350 1351 /** 1352 * Sets the enum option key. 1353 * 1354 * @param enumOptionKey the enum option key 1355 */ 1356 public void setEnumOptionKey(String enumOptionKey) { 1357 this.enumOptionKey = enumOptionKey; 1358 } 1359 1360 /** 1361 * Gets the multi-select option key. 1362 * 1363 * @return the key. 1364 */ 1365 public String getMultiSelectOptionKey() { 1366 return this.multiSelectOptionKey; 1367 } 1368 1369 /** 1370 * Sets the multi-select option key. 1371 * 1372 * @param key the key. 1373 */ 1374 public void setMultiSelectOptionKey(String key) { 1375 this.multiSelectOptionKey = key; 1376 } 1377 1378 /** 1379 * Gets the list of multiselect option keys. 1380 * 1381 * @return the list of keys. 1382 */ 1383 public List<String> getMultiSelectOptionKeys() { 1384 return this.multiSelectOptionKeys; 1385 } 1386 1387 /** 1388 * Sets the multi-select option keys. 1389 * 1390 * @param keys the list of keys. 1391 */ 1392 public void setMultiSelectOptionKeys(List<String> keys) { 1393 this.multiSelectOptionKeys = keys; 1394 } 1395 1396 @Override 1397 public void clearPendingChanges() { 1398 super.clearPendingChanges(); 1399 } 1400 1401 /** 1402 * {@inheritDoc} 1403 */ 1404 @Override 1405 void parseJSONMember(JsonObject.Member member) { 1406 JsonValue value = member.getValue(); 1407 String memberName = member.getName(); 1408 switch (memberName) { 1409 case "op": 1410 this.op = Operation.valueOf(value.asString()); 1411 break; 1412 case "data": 1413 this.data = new Field(value.asObject()); 1414 break; 1415 case "fieldKey": 1416 this.fieldKey = value.asString(); 1417 break; 1418 case "fieldKeys": 1419 if (this.fieldKeys == null) { 1420 this.fieldKeys = new ArrayList<>(); 1421 } else { 1422 this.fieldKeys.clear(); 1423 } 1424 for (JsonValue jsonValue : value.asArray()) { 1425 this.fieldKeys.add(jsonValue.asString()); 1426 } 1427 break; 1428 case "enumOptionKeys": 1429 if (this.enumOptionKeys == null) { 1430 this.enumOptionKeys = new ArrayList<>(); 1431 } else { 1432 this.enumOptionKeys.clear(); 1433 } 1434 1435 for (JsonValue jsonValue : value.asArray()) { 1436 this.enumOptionKeys.add(jsonValue.asString()); 1437 } 1438 break; 1439 case "enumOptionKey": 1440 this.enumOptionKey = value.asString(); 1441 break; 1442 case "multiSelectOptionKey": 1443 this.multiSelectOptionKey = value.asString(); 1444 break; 1445 case "multiSelectOptionKeys": 1446 this.multiSelectOptionKeys = new ArrayList<>(); 1447 for (JsonValue key : value.asArray()) { 1448 this.multiSelectOptionKeys.add(key.asString()); 1449 } 1450 break; 1451 default: 1452 break; 1453 } 1454 } 1455 } 1456}