All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.box.sdk.MetadataTemplate Maven / Gradle / Ivy

There is a newer version: 4.11.1
Show newest version
package com.box.sdk;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.eclipsesource.json.JsonArray;
import com.eclipsesource.json.JsonObject;
import com.eclipsesource.json.JsonValue;

/**
 * The MetadataTemplate class represents the Box metadata template object.
 * Templates allow the metadata service to provide a multitude of services,
 * such as pre-defining sets of key:value pairs or schema enforcement on specific fields.
 *
 * @see Box metadata templates
 */
public class MetadataTemplate extends BoxJSONObject {

    /**
     * @see #getMetadataTemplate(BoxAPIConnection)
     */
    public static final URLTemplate METADATA_TEMPLATE_URL_TEMPLATE
        = new URLTemplate("metadata_templates/%s/%s/schema");

    /**
     * @see #getMetadataTemplateByID(BoxAPIConnection, String)
     */
    public static final URLTemplate METADATA_TEMPLATE_BY_ID_URL_TEMPLATE = new URLTemplate("metadata_templates/%s");

    /**
     * @see #createMetadataTemplate(BoxAPIConnection, String, String, String, boolean, List)
     */
    public static final URLTemplate METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE
        = new URLTemplate("metadata_templates/schema");

    /**
     * @see #getEnterpriseMetadataTemplates(String, int, BoxAPIConnection, String...)
     */
    public static final URLTemplate ENTERPRISE_METADATA_URL_TEMPLATE = new URLTemplate("metadata_templates/%s");

    /**
     *
     */
    private static final URLTemplate METADATA_QUERIES_URL_TEMPLATE = new URLTemplate("metadata_queries/execute_read");

    /**
     * Default metadata type to be used in query.
     */
    private static final String DEFAULT_METADATA_TYPE = "properties";

    /**
     * Global metadata scope. Used by default if the metadata type is "properties".
     */
    private static final String GLOBAL_METADATA_SCOPE = "global";

    /**
     * Enterprise metadata scope. Used by default if the metadata type is not "properties".
     */
    private static final String ENTERPRISE_METADATA_SCOPE = "enterprise";

    /**
     * Default number of entries per page.
     */
    private static final int DEFAULT_ENTRIES_LIMIT = 100;

    /**
     * @see #getID()
     */
    private String id;

    /**
     * @see #getTemplateKey()
     */
    private String templateKey;

    /**
     * @see #getScope()
     */
    private String scope;

    /**
     * @see #getDisplayName()
     */
    private String displayName;

    /**
     * @see #getIsHidden()
     */
    private Boolean isHidden;

    /**
     * @see #getFields()
     */
    private List fields;

    /**
     * Constructs an empty metadata template.
     */
    public MetadataTemplate() {
        super();
    }

    /**
     * Constructs a metadata template from a JSON string.
     * @param json the json encoded metadate template.
     */
    public MetadataTemplate(String json) {
        super(json);
    }

    /**
     * Constructs a metadate template from a JSON object.
     * @param jsonObject the json encoded metadate template.
     */
    MetadataTemplate(JsonObject jsonObject) {
        super(jsonObject);
    }

    /**
     * Gets the ID of the template.
     * @return the template ID.
     */
    public String getID() {
        return this.id;
    }

    /**
     * Gets the unique template key to identify the metadata template.
     * @return the unique template key to identify the metadata template.
     */
    public String getTemplateKey() {
        return this.templateKey;
    }

    /**
     * Gets the metadata template scope.
     * @return the metadata template scope.
     */
    public String getScope() {
        return this.scope;
    }

    /**
     * Gets the displayed metadata template name.
     * @return the displayed metadata template name.
     */
    public String getDisplayName() {
        return this.displayName;
    }

    /**
     * Gets is the metadata template hidden.
     * @return is the metadata template hidden.
     */
    public Boolean getIsHidden() {
        return this.isHidden;
    }

    /**
     * Gets the iterable with all fields the metadata template contains.
     * @return the iterable with all fields the metadata template contains.
     */
    public List getFields() {
        return this.fields;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    void parseJSONMember(JsonObject.Member member) {
        JsonValue value = member.getValue();
        String memberName = member.getName();
        if (memberName.equals("templateKey")) {
            this.templateKey = value.asString();
        } else if (memberName.equals("scope")) {
            this.scope = value.asString();
        } else if (memberName.equals("displayName")) {
            this.displayName = value.asString();
        } else if (memberName.equals("hidden")) {
            this.isHidden = value.asBoolean();
        } else if (memberName.equals("fields")) {
            this.fields = new ArrayList();
            for (JsonValue field: value.asArray()) {
                this.fields.add(new Field(field.asObject()));
            }
        } else if (memberName.equals("id")) {
            this.id = value.asString();
        }
    }

    /**
     * Creates new metadata template.
     * @param api the API connection to be used.
     * @param scope the scope of the object.
     * @param templateKey a unique identifier for the template.
     * @param displayName the display name of the field.
     * @param hidden whether this template is hidden in the UI.
     * @param fields the ordered set of fields for the template
     * @return the metadata template returned from the server.
     */
    public static MetadataTemplate createMetadataTemplate(BoxAPIConnection api, String scope, String templateKey,
            String displayName, boolean hidden, List fields) {

        JsonObject jsonObject = new JsonObject();
        jsonObject.add("scope", scope);
        jsonObject.add("displayName", displayName);
        jsonObject.add("hidden", hidden);

        if (templateKey != null) {
            jsonObject.add("templateKey", templateKey);
        }

        JsonArray fieldsArray = new JsonArray();
        if (fields != null && !fields.isEmpty()) {
            for (Field field : fields) {
                JsonObject fieldObj = getFieldJsonObject(field);

                fieldsArray.add(fieldObj);
            }

            jsonObject.add("fields", fieldsArray);
        }

        URL url = METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE.build(api.getBaseURL());
        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
        request.setBody(jsonObject.toString());

        BoxJSONResponse response = (BoxJSONResponse) request.send();
        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());

        return new MetadataTemplate(responseJSON);
    }

    /**
     * Gets the JsonObject representation of the given field object.
     * @param field represents a template field
     * @return the json object
     */
    private static JsonObject getFieldJsonObject(Field field) {
        JsonObject fieldObj = new JsonObject();
        fieldObj.add("type", field.getType());
        fieldObj.add("key", field.getKey());
        fieldObj.add("displayName", field.getDisplayName());

        String fieldDesc = field.getDescription();
        if (fieldDesc != null) {
            fieldObj.add("description", field.getDescription());
        }

        Boolean fieldIsHidden = field.getIsHidden();
        if (fieldIsHidden != null) {
            fieldObj.add("hidden", field.getIsHidden());
        }

        JsonArray array = new JsonArray();
        List options = field.getOptions();
        if (options != null && !options.isEmpty()) {
            for (String option : options) {
                JsonObject optionObj = new JsonObject();
                optionObj.add("key", option);

                array.add(optionObj);
            }
            fieldObj.add("options", array);
        }

        return fieldObj;
    }

    /**
     * Updates the schema of an existing metadata template.
     *
     * @param api the API connection to be used
     * @param scope the scope of the object
     * @param template Unique identifier of the template
     * @param fieldOperations the fields that needs to be updated / added in the template
     * @return the updated metadata template
     */
    public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template,
            List fieldOperations) {

        JsonArray array = new JsonArray();

        for (FieldOperation fieldOperation : fieldOperations) {
            JsonObject jsonObject = getFieldOperationJsonObject(fieldOperation);
            array.add(jsonObject);
        }

        QueryStringBuilder builder = new QueryStringBuilder();
        URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlpha(api.getBaseURL(), scope, template);
        BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
        request.setBody(array.toString());

        BoxJSONResponse response = (BoxJSONResponse) request.send();
        JsonObject responseJson = JsonObject.readFrom(response.getJSON());

        return new MetadataTemplate(responseJson);
    }

    /**
     * Deletes the schema of an existing metadata template.
     *
     * @param api the API connection to be used
     * @param scope the scope of the object
     * @param template Unique identifier of the template
     */
    public static void deleteMetadataTemplate(BoxAPIConnection api, String scope, String template) {

        URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlpha(api.getBaseURL(), scope, template);
        BoxJSONRequest request = new BoxJSONRequest(api, url, "DELETE");

        request.send();
    }

    /**
     * Executes a metadata query.
     *
     * @param api The API connection to be used
     * @param from The template used in the query. Must be in the form scope.templateKey
     * @param ancestorFolderId The folder_id to which to restrain the query
     * @return An iterable of BoxMetadataQueryItem search results
     */
    public static BoxResourceIterable executeMetadataQuery(final BoxAPIConnection api,
                                                            String from, String ancestorFolderId) {
        return executeMetadataQuery(api, from, null, null, ancestorFolderId, null, null, 100, null);
    }

    /**
      * Executes a metadata query.
      *
      * @param api The API connection to be used
      * @param from The template used in the query. Must be in the form scope.templateKey
      * @param query The logical expression of the query
      * @param queryParameters Required if query present. The arguments for the query
      * @param ancestorFolderId The folder_id to which to restrain the query
      * @return An iterable of BoxMetadataQueryItem search results
      */
    public static BoxResourceIterable executeMetadataQuery(final BoxAPIConnection api,
                                                            String from, String query, JsonObject queryParameters,
                                                            String ancestorFolderId) {
        return executeMetadataQuery(api, from, query, queryParameters, ancestorFolderId, null, null, 100, null);
    }

    /**
      * Executes a metadata query.
      *
      * @param api The API connection to be used
      * @param from The template used in the query. Must be in the form scope.templateKey
      * @param query The logical expression of the query
      * @param queryParameters Required if query present. The arguments for the query
      * @param ancestorFolderId The folder_id to which to restrain the query
      * @param indexName The name of the Index to use
      * @param orderBy The field_key(s) to order on and the corresponding direction(s)
      * @return An iterable of BoxMetadataQueryItem search results
      */
    public static BoxResourceIterable executeMetadataQuery(final BoxAPIConnection api,
                                                            String from, String query, JsonObject queryParameters,
                                                            String ancestorFolderId, String indexName,
                                                            JsonArray orderBy) {
        return executeMetadataQuery(api, from, query, queryParameters, ancestorFolderId, indexName, orderBy, 100, null);
    }

    /**
     * Executes a metadata query.
     *
     * @param api The API connection to be used
     * @param from The template used in the query. Must be in the form scope.templateKey
     * @param query The logical expression of the query
     * @param queryParameters Required if query present. The arguments for the query
     * @param ancestorFolderId The folder_id to which to restrain the query
     * @param indexName The name of the Index to use
     * @param orderBy The field_key(s) to order on and the corresponding direction(s)
     * @param limit Max results to return for a single request (0-100 inclusive)
     * @param marker The marker to use for requesting the next page
     * @return An iterable of BoxMetadataQueryItem search results
     */
    public static BoxResourceIterable executeMetadataQuery(final BoxAPIConnection api,
                                                            String from, String query, JsonObject queryParameters,
                                                            String ancestorFolderId, String indexName,
                                                            JsonArray orderBy, int limit, String marker) {

        JsonObject jsonObject = new JsonObject().add("from", from);
        if (query != null) {
            jsonObject.add("query", query);
        }
        if (queryParameters != null) {
            jsonObject.add("query_params", queryParameters);
        }
        if (ancestorFolderId != null) {
            jsonObject.add("ancestor_folder_id", ancestorFolderId);
        }
        if (indexName != null) {
            jsonObject.add("use_index", indexName);
        }
        if (orderBy != null) {
            jsonObject.add("order_by", orderBy);
        }
        jsonObject.add("limit", limit);
        if (marker != null) {
            jsonObject.add("marker", marker);
        }

        URL url = METADATA_QUERIES_URL_TEMPLATE.build(api.getBaseURL());
        return new BoxResourceIterable(api, url, limit, jsonObject, marker) {

            @Override
            protected BoxMetadataQueryItem factory(JsonObject jsonObject) {
                return new BoxMetadataQueryItem(jsonObject, api);
            }
        };
    }

    /**
     * Gets the JsonObject representation of the Field Operation.
     * @param fieldOperation represents the template update operation
     * @return the json object
     */
    private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperation) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.add("op", fieldOperation.getOp().toString());

        String fieldKey = fieldOperation.getFieldKey();
        if (fieldKey != null) {
            jsonObject.add("fieldKey", fieldKey);
        }

        Field field = fieldOperation.getData();
        if (field != null) {
            JsonObject fieldObj = new JsonObject();

            String type = field.getType();
            if (type != null) {
                fieldObj.add("type", type);
            }

            String key = field.getKey();
            if (key != null) {
                fieldObj.add("key", key);
            }

            String displayName = field.getDisplayName();
            if (displayName != null) {
                fieldObj.add("displayName", displayName);
            }

            String description = field.getDescription();
            if (description != null) {
                fieldObj.add("description", description);
            }

            Boolean hidden = field.getIsHidden();
            if (hidden != null) {
                fieldObj.add("hidden", hidden);
            }

            List options = field.getOptions();
            if (options != null) {
                JsonArray array = new JsonArray();
                for (String option: options) {
                    JsonObject optionObj = new JsonObject();
                    optionObj.add("key", option);

                    array.add(optionObj);
                }

                fieldObj.add("options", array);
            }

            jsonObject.add("data", fieldObj);
        }

        List fieldKeys = fieldOperation.getFieldKeys();
        if (fieldKeys != null) {
            jsonObject.add("fieldKeys", getJsonArray(fieldKeys));
        }

        List enumOptionKeys = fieldOperation.getEnumOptionKeys();
        if (enumOptionKeys != null) {
            jsonObject.add("enumOptionKeys", getJsonArray(enumOptionKeys));
        }

        String enumOptionKey = fieldOperation.getEnumOptionKey();
        if (enumOptionKey != null) {
            jsonObject.add("enumOptionKey", enumOptionKey);
        }

        String multiSelectOptionKey = fieldOperation.getMultiSelectOptionKey();
        if (multiSelectOptionKey != null) {
            jsonObject.add("multiSelectOptionKey", multiSelectOptionKey);
        }

        List multiSelectOptionKeys = fieldOperation.getMultiSelectOptionKeys();
        if (multiSelectOptionKeys != null) {
            jsonObject.add("multiSelectOptionKeys", getJsonArray(multiSelectOptionKeys));
        }

        return jsonObject;
    }

    /**
     * Gets the Json Array representation of the given list of strings.
     * @param keys List of strings
     * @return the JsonArray represents the list of keys
     */
    private static JsonArray getJsonArray(List keys) {
        JsonArray array = new JsonArray();
        for (String key : keys) {
            array.add(key);
        }

        return array;
    }

    /**
     * Gets the metadata template of properties.
     * @param api the API connection to be used.
     * @return the metadata template returned from the server.
     */
    public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api) {
        return getMetadataTemplate(api, DEFAULT_METADATA_TYPE);
    }

    /**
     * Gets the metadata template of specified template type.
     * @param api the API connection to be used.
     * @param templateName the metadata template type name.
     * @return the metadata template returned from the server.
     */
    public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api, String templateName) {
        String scope = scopeBasedOnType(templateName);
        return getMetadataTemplate(api, templateName, scope);
    }

    /**
     * Gets the metadata template of specified template type.
     * @param api the API connection to be used.
     * @param templateName the metadata template type name.
     * @param scope the metadata template scope (global or enterprise).
     * @param fields the fields to retrieve.
     * @return the metadata template returned from the server.
     */
    public static MetadataTemplate getMetadataTemplate(
            BoxAPIConnection api, String templateName, String scope, String ... fields) {
        QueryStringBuilder builder = new QueryStringBuilder();
        if (fields.length > 0) {
            builder.appendParam("fields", fields);
        }
        URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildAlphaWithQuery(
                api.getBaseURL(), builder.toString(), scope, templateName);
        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
        BoxJSONResponse response = (BoxJSONResponse) request.send();
        return new MetadataTemplate(response.getJSON());
    }

    /**
     * Geta the specified metadata template by its ID.
     * @param api the API connection to be used.
     * @param templateID the ID of the template to get.
     * @return the metadata template object.
     */
    public static MetadataTemplate getMetadataTemplateByID(BoxAPIConnection api, String templateID) {

        URL url = METADATA_TEMPLATE_BY_ID_URL_TEMPLATE.buildAlpha(api.getBaseURL(), templateID);
        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
        BoxJSONResponse response = (BoxJSONResponse) request.send();
        return new MetadataTemplate(response.getJSON());
    }

    /**
     * Returns all metadata templates within a user's enterprise.
     * @param api the API connection to be used.
     * @param fields the fields to retrieve.
     * @return the metadata template returned from the server.
     */
    public static Iterable getEnterpriseMetadataTemplates(BoxAPIConnection api, String ... fields) {
        return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, api, fields);
    }

    /**
     * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
     * @param scope the scope of the metadata templates.
     * @param api the API connection to be used.
     * @param fields the fields to retrieve.
     * @return the metadata template returned from the server.
     */
    public static Iterable getEnterpriseMetadataTemplates(
            String scope, BoxAPIConnection api, String ... fields) {
        return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, DEFAULT_ENTRIES_LIMIT, api, fields);
    }

    /**
     * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
     * @param scope the scope of the metadata templates.
     * @param limit maximum number of entries per response.
     * @param api the API connection to be used.
     * @param fields the fields to retrieve.
     * @return the metadata template returned from the server.
     */
    public static Iterable getEnterpriseMetadataTemplates(
            String scope, int limit, BoxAPIConnection api, String ... fields) {
        QueryStringBuilder builder = new QueryStringBuilder();
        if (fields.length > 0) {
            builder.appendParam("fields", fields);
        }
        return new BoxResourceIterable(
                api, ENTERPRISE_METADATA_URL_TEMPLATE.buildAlphaWithQuery(
                        api.getBaseURL(), builder.toString(), scope), limit) {

            @Override
            protected MetadataTemplate factory(JsonObject jsonObject) {
                return new MetadataTemplate(jsonObject);
            }
        };
    }

    /**
     * Determines the metadata scope based on type.
     * @param typeName type of the metadata.
     * @return scope of the metadata.
     */
    private static String scopeBasedOnType(String typeName) {
        return typeName.equals(DEFAULT_METADATA_TYPE) ? GLOBAL_METADATA_SCOPE : ENTERPRISE_METADATA_SCOPE;
    }

    /**
     * Class contains information about the metadata template field.
     */
    public static class Field extends BoxJSONObject {

        /**
         * @see #getID()
         */
        private String id;

        /**
         * @see #getType()
         */
        private String type;

        /**
         * @see #getKey()
         */
        private String key;

        /**
         * @see #getDisplayName()
         */
        private String displayName;

        /**
         * @see #getIsHidden()
         */
        private Boolean isHidden;

        /**
         * @see #getDescription()
         */
        private String description;

        /**
         * @see #getOptionsObject()
         */
        private List




© 2015 - 2024 Weber Informatics LLC | Privacy Policy