001package com.box.sdk;
002
003import java.net.URL;
004import java.util.ArrayList;
005import java.util.List;
006
007import com.eclipsesource.json.JsonArray;
008import com.eclipsesource.json.JsonObject;
009import com.eclipsesource.json.JsonValue;
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://docs.box.com/reference#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     * Default metadata type to be used in query.
044     */
045    private static final String DEFAULT_METADATA_TYPE = "properties";
046
047    /**
048     * Global metadata scope. Used by default if the metadata type is "properties".
049     */
050    private static final String GLOBAL_METADATA_SCOPE = "global";
051
052    /**
053     * Enterprise metadata scope. Used by default if the metadata type is not "properties".
054     */
055    private static final String ENTERPRISE_METADATA_SCOPE = "enterprise";
056
057    /**
058     * Default number of entries per page.
059     */
060    private static final int DEFAULT_ENTRIES_LIMIT = 100;
061
062    /**
063     * @see #getID()
064     */
065    private String id;
066
067    /**
068     * @see #getTemplateKey()
069     */
070    private String templateKey;
071
072    /**
073     * @see #getScope()
074     */
075    private String scope;
076
077    /**
078     * @see #getDisplayName()
079     */
080    private String displayName;
081
082    /**
083     * @see #getIsHidden()
084     */
085    private Boolean isHidden;
086
087    /**
088     * @see #getFields()
089     */
090    private List<Field> fields;
091
092    /**
093     * Constructs an empty metadata template.
094     */
095    public MetadataTemplate() {
096        super();
097    }
098
099    /**
100     * Constructs a metadata template from a JSON string.
101     * @param json the json encoded metadate template.
102     */
103    public MetadataTemplate(String json) {
104        super(json);
105    }
106
107    /**
108     * Constructs a metadate template from a JSON object.
109     * @param jsonObject the json encoded metadate template.
110     */
111    MetadataTemplate(JsonObject jsonObject) {
112        super(jsonObject);
113    }
114
115    /**
116     * Gets the ID of the template.
117     * @return the template ID.
118     */
119    public String getID() {
120        return this.id;
121    }
122
123    /**
124     * Gets the unique template key to identify the metadata template.
125     * @return the unique template key to identify the metadata template.
126     */
127    public String getTemplateKey() {
128        return this.templateKey;
129    }
130
131    /**
132     * Gets the metadata template scope.
133     * @return the metadata template scope.
134     */
135    public String getScope() {
136        return this.scope;
137    }
138
139    /**
140     * Gets the displayed metadata template name.
141     * @return the displayed metadata template name.
142     */
143    public String getDisplayName() {
144        return this.displayName;
145    }
146
147    /**
148     * Gets is the metadata template hidden.
149     * @return is the metadata template hidden.
150     */
151    public Boolean getIsHidden() {
152        return this.isHidden;
153    }
154
155    /**
156     * Gets the iterable with all fields the metadata template contains.
157     * @return the iterable with all fields the metadata template contains.
158     */
159    public List<Field> getFields() {
160        return this.fields;
161    }
162
163    /**
164     * {@inheritDoc}
165     */
166    @Override
167    void parseJSONMember(JsonObject.Member member) {
168        JsonValue value = member.getValue();
169        String memberName = member.getName();
170        if (memberName.equals("templateKey")) {
171            this.templateKey = value.asString();
172        } else if (memberName.equals("scope")) {
173            this.scope = value.asString();
174        } else if (memberName.equals("displayName")) {
175            this.displayName = value.asString();
176        } else if (memberName.equals("hidden")) {
177            this.isHidden = value.asBoolean();
178        } else if (memberName.equals("fields")) {
179            this.fields = new ArrayList<Field>();
180            for (JsonValue field: value.asArray()) {
181                this.fields.add(new Field(field.asObject()));
182            }
183        } else if (memberName.equals("id")) {
184            this.id = value.asString();
185        }
186    }
187
188    /**
189     * Creates new metadata template.
190     * @param api the API connection to be used.
191     * @param scope the scope of the object.
192     * @param templateKey a unique identifier for the template.
193     * @param displayName the display name of the field.
194     * @param hidden whether this template is hidden in the UI.
195     * @param fields the ordered set of fields for the template
196     * @return the metadata template returned from the server.
197     */
198    public static MetadataTemplate createMetadataTemplate(BoxAPIConnection api, String scope, String templateKey,
199            String displayName, boolean hidden, List<Field> fields) {
200
201        JsonObject jsonObject = new JsonObject();
202        jsonObject.add("scope", scope);
203        jsonObject.add("displayName", displayName);
204        jsonObject.add("hidden", hidden);
205
206        if (templateKey != null) {
207            jsonObject.add("templateKey", templateKey);
208        }
209
210        JsonArray fieldsArray = new JsonArray();
211        if (fields != null && !fields.isEmpty()) {
212            for (Field field : fields) {
213                JsonObject fieldObj = getFieldJsonObject(field);
214
215                fieldsArray.add(fieldObj);
216            }
217
218            jsonObject.add("fields", fieldsArray);
219        }
220
221        URL url = METADATA_TEMPLATE_SCHEMA_URL_TEMPLATE.build(api.getBaseURL());
222        BoxJSONRequest request = new BoxJSONRequest(api, url, "POST");
223        request.setBody(jsonObject.toString());
224
225        BoxJSONResponse response = (BoxJSONResponse) request.send();
226        JsonObject responseJSON = JsonObject.readFrom(response.getJSON());
227
228        return new MetadataTemplate(responseJSON);
229    }
230
231    /**
232     * Gets the JsonObject representation of the given field object.
233     * @param field represents a template field
234     * @return the json object
235     */
236    private static JsonObject getFieldJsonObject(Field field) {
237        JsonObject fieldObj = new JsonObject();
238        fieldObj.add("type", field.getType());
239        fieldObj.add("key", field.getKey());
240        fieldObj.add("displayName", field.getDisplayName());
241
242        String fieldDesc = field.getDescription();
243        if (fieldDesc != null) {
244            fieldObj.add("description", field.getDescription());
245        }
246
247        Boolean fieldIsHidden = field.getIsHidden();
248        if (fieldIsHidden != null) {
249            fieldObj.add("hidden", field.getIsHidden());
250        }
251
252        JsonArray array = new JsonArray();
253        List<String> options = field.getOptions();
254        if (options != null && !options.isEmpty()) {
255            for (String option : options) {
256                JsonObject optionObj = new JsonObject();
257                optionObj.add("key", option);
258
259                array.add(optionObj);
260            }
261            fieldObj.add("options", array);
262        }
263
264        return fieldObj;
265    }
266
267    /**
268     * Updates the schema of an existing metadata template.
269     *
270     * @param api the API connection to be used
271     * @param scope the scope of the object
272     * @param template Unique identifier of the template
273     * @param fieldOperations the fields that needs to be updated / added in the template
274     * @return the updated metadata template
275     */
276    public static MetadataTemplate updateMetadataTemplate(BoxAPIConnection api, String scope, String template,
277            List<FieldOperation> fieldOperations) {
278
279        JsonArray array = new JsonArray();
280
281        for (FieldOperation fieldOperation : fieldOperations) {
282            JsonObject jsonObject = getFieldOperationJsonObject(fieldOperation);
283            array.add(jsonObject);
284        }
285
286        QueryStringBuilder builder = new QueryStringBuilder();
287        URL url = METADATA_TEMPLATE_URL_TEMPLATE.build(api.getBaseURL(), scope, template);
288        BoxJSONRequest request = new BoxJSONRequest(api, url, "PUT");
289        request.setBody(array.toString());
290
291        BoxJSONResponse response = (BoxJSONResponse) request.send();
292        JsonObject responseJson = JsonObject.readFrom(response.getJSON());
293
294        return new MetadataTemplate(responseJson);
295    }
296
297    /**
298     * Deletes the schema of an existing metadata template.
299     *
300     * @param api the API connection to be used
301     * @param scope the scope of the object
302     * @param template Unique identifier of the template
303     */
304    public static void deleteMetadataTemplate(BoxAPIConnection api, String scope, String template) {
305
306        URL url = METADATA_TEMPLATE_URL_TEMPLATE.build(api.getBaseURL(), scope, template);
307        BoxJSONRequest request = new BoxJSONRequest(api, url, "DELETE");
308
309        request.send();
310    }
311
312    /**
313     * Gets the JsonObject representation of the Field Operation.
314     * @param fieldOperation represents the template update operation
315     * @return the json object
316     */
317    private static JsonObject getFieldOperationJsonObject(FieldOperation fieldOperation) {
318        JsonObject jsonObject = new JsonObject();
319        jsonObject.add("op", fieldOperation.getOp().toString());
320
321        String fieldKey = fieldOperation.getFieldKey();
322        if (fieldKey != null) {
323            jsonObject.add("fieldKey", fieldKey);
324        }
325
326        Field field = fieldOperation.getData();
327        if (field != null) {
328            JsonObject fieldObj = new JsonObject();
329
330            String type = field.getType();
331            if (type != null) {
332                fieldObj.add("type", type);
333            }
334
335            String key = field.getKey();
336            if (key != null) {
337                fieldObj.add("key", key);
338            }
339
340            String displayName = field.getDisplayName();
341            if (displayName != null) {
342                fieldObj.add("displayName", displayName);
343            }
344
345            String description = field.getDescription();
346            if (description != null) {
347                fieldObj.add("description", description);
348            }
349
350            Boolean hidden = field.getIsHidden();
351            if (hidden != null) {
352                fieldObj.add("hidden", hidden);
353            }
354
355            List<String> options = field.getOptions();
356            if (options != null) {
357                JsonArray array = new JsonArray();
358                for (String option: options) {
359                    JsonObject optionObj = new JsonObject();
360                    optionObj.add("key", option);
361
362                    array.add(optionObj);
363                }
364
365                fieldObj.add("options", array);
366            }
367
368            jsonObject.add("data", fieldObj);
369        }
370
371        List<String> fieldKeys = fieldOperation.getFieldKeys();
372        if (fieldKeys != null) {
373            jsonObject.add("fieldKeys", getJsonArray(fieldKeys));
374        }
375
376        List<String> enumOptionKeys = fieldOperation.getEnumOptionKeys();
377        if (enumOptionKeys != null) {
378            jsonObject.add("enumOptionKeys", getJsonArray(enumOptionKeys));
379        }
380
381        String enumOptionKey = fieldOperation.getEnumOptionKey();
382        if (enumOptionKey != null) {
383            jsonObject.add("enumOptionKey", enumOptionKey);
384        }
385
386        String multiSelectOptionKey = fieldOperation.getMultiSelectOptionKey();
387        if (multiSelectOptionKey != null) {
388            jsonObject.add("multiSelectOptionKey", multiSelectOptionKey);
389        }
390
391        List<String> multiSelectOptionKeys = fieldOperation.getMultiSelectOptionKeys();
392        if (multiSelectOptionKeys != null) {
393            jsonObject.add("multiSelectOptionKeys", getJsonArray(multiSelectOptionKeys));
394        }
395
396        return jsonObject;
397    }
398
399    /**
400     * Gets the Json Array representation of the given list of strings.
401     * @param keys List of strings
402     * @return the JsonArray represents the list of keys
403     */
404    private static JsonArray getJsonArray(List<String> keys) {
405        JsonArray array = new JsonArray();
406        for (String key : keys) {
407            array.add(key);
408        }
409
410        return array;
411    }
412
413    /**
414     * Gets the metadata template of properties.
415     * @param api the API connection to be used.
416     * @return the metadata template returned from the server.
417     */
418    public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api) {
419        return getMetadataTemplate(api, DEFAULT_METADATA_TYPE);
420    }
421
422    /**
423     * Gets the metadata template of specified template type.
424     * @param api the API connection to be used.
425     * @param templateName the metadata template type name.
426     * @return the metadata template returned from the server.
427     */
428    public static MetadataTemplate getMetadataTemplate(BoxAPIConnection api, String templateName) {
429        String scope = scopeBasedOnType(templateName);
430        return getMetadataTemplate(api, templateName, scope);
431    }
432
433    /**
434     * Gets the metadata template of specified template type.
435     * @param api the API connection to be used.
436     * @param templateName the metadata template type name.
437     * @param scope the metadata template scope (global or enterprise).
438     * @param fields the fields to retrieve.
439     * @return the metadata template returned from the server.
440     */
441    public static MetadataTemplate getMetadataTemplate(
442            BoxAPIConnection api, String templateName, String scope, String ... fields) {
443        QueryStringBuilder builder = new QueryStringBuilder();
444        if (fields.length > 0) {
445            builder.appendParam("fields", fields);
446        }
447        URL url = METADATA_TEMPLATE_URL_TEMPLATE.buildWithQuery(
448                api.getBaseURL(), builder.toString(), scope, templateName);
449        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
450        BoxJSONResponse response = (BoxJSONResponse) request.send();
451        return new MetadataTemplate(response.getJSON());
452    }
453
454    /**
455     * Geta the specified metadata template by its ID.
456     * @param api the API connection to be used.
457     * @param templateID the ID of the template to get.
458     * @return the metadata template object.
459     */
460    public static MetadataTemplate getMetadataTemplateByID(BoxAPIConnection api, String templateID) {
461
462        URL url = METADATA_TEMPLATE_BY_ID_URL_TEMPLATE.build(api.getBaseURL(), templateID);
463        BoxAPIRequest request = new BoxAPIRequest(api, url, "GET");
464        BoxJSONResponse response = (BoxJSONResponse) request.send();
465        return new MetadataTemplate(response.getJSON());
466    }
467
468    /**
469     * Returns all metadata templates within a user's enterprise.
470     * @param api the API connection to be used.
471     * @param fields the fields to retrieve.
472     * @return the metadata template returned from the server.
473     */
474    public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates(BoxAPIConnection api, String ... fields) {
475        return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, api, fields);
476    }
477
478    /**
479     * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
480     * @param scope the scope of the metadata templates.
481     * @param api the API connection to be used.
482     * @param fields the fields to retrieve.
483     * @return the metadata template returned from the server.
484     */
485    public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates(
486            String scope, BoxAPIConnection api, String ... fields) {
487        return getEnterpriseMetadataTemplates(ENTERPRISE_METADATA_SCOPE, DEFAULT_ENTRIES_LIMIT, api, fields);
488    }
489
490    /**
491     * Returns all metadata templates within a user's scope. Currently only the enterprise scope is supported.
492     * @param scope the scope of the metadata templates.
493     * @param limit maximum number of entries per response.
494     * @param api the API connection to be used.
495     * @param fields the fields to retrieve.
496     * @return the metadata template returned from the server.
497     */
498    public static Iterable<MetadataTemplate> getEnterpriseMetadataTemplates(
499            String scope, int limit, BoxAPIConnection api, String ... fields) {
500        QueryStringBuilder builder = new QueryStringBuilder();
501        if (fields.length > 0) {
502            builder.appendParam("fields", fields);
503        }
504        return new BoxResourceIterable<MetadataTemplate>(
505                api, ENTERPRISE_METADATA_URL_TEMPLATE.buildWithQuery(
506                        api.getBaseURL(), builder.toString(), scope), limit) {
507
508            @Override
509            protected MetadataTemplate factory(JsonObject jsonObject) {
510                return new MetadataTemplate(jsonObject);
511            }
512        };
513    }
514
515    /**
516     * Determines the metadata scope based on type.
517     * @param typeName type of the metadata.
518     * @return scope of the metadata.
519     */
520    private static String scopeBasedOnType(String typeName) {
521        return typeName.equals(DEFAULT_METADATA_TYPE) ? GLOBAL_METADATA_SCOPE : ENTERPRISE_METADATA_SCOPE;
522    }
523
524    /**
525     * Class contains information about the metadata template field.
526     */
527    public static class Field extends BoxJSONObject {
528
529        /**
530         * @see #getID()
531         */
532        private String id;
533
534        /**
535         * @see #getType()
536         */
537        private String type;
538
539        /**
540         * @see #getKey()
541         */
542        private String key;
543
544        /**
545         * @see #getDisplayName()
546         */
547        private String displayName;
548
549        /**
550         * @see #getIsHidden()
551         */
552        private Boolean isHidden;
553
554        /**
555         * @see #getDescription()
556         */
557        private String description;
558
559        /**
560         * @see #getOptions()
561         */
562        private List<String> options;
563
564        /**
565         * Constructs an empty metadata template.
566         */
567        public Field() {
568            super();
569        }
570
571        /**
572         * Constructs a metadate template field from a JSON string.
573         * @param json the json encoded metadate template field.
574         */
575        public Field(String json) {
576            super(json);
577        }
578
579        /**
580         * Constructs a metadate template field from a JSON object.
581         * @param jsonObject the json encoded metadate template field.
582         */
583        Field(JsonObject jsonObject) {
584            super(jsonObject);
585        }
586
587        /**
588         * Gets the ID of the template field.
589         * @return the template field ID.
590         */
591        public String getID() {
592            return this.id;
593        }
594
595        /**
596         * Gets the data type of the field's value.
597         * @return the data type of the field's value.
598         */
599        public String getType() {
600            return this.type;
601        }
602
603        /**
604         * Sets the data type of the field's value.
605         * @param type the data type of the field's value.
606         */
607        public void setType(String type) {
608            this.type = type;
609        }
610
611        /**
612         * Gets the key of the field.
613         * @return the key of the field.
614         */
615        public String getKey() {
616            return this.key;
617        }
618
619        /**
620         * Sets the key of the field.
621         * @param key the key of the field.
622         */
623        public void setKey(String key) {
624            this.key = key;
625        }
626
627        /**
628         * Gets the display name of the field.
629         * @return the display name of the field.
630         */
631        public String getDisplayName() {
632            return this.displayName;
633        }
634
635        /**
636         * Sets the display name of the field.
637         * @param displayName the display name of the field.
638         */
639        public void setDisplayName(String displayName) {
640            this.displayName = displayName;
641        }
642
643        /**
644         * Gets is metadata template field hidden.
645         * @return is metadata template field hidden.
646         */
647        public Boolean getIsHidden() {
648            return this.isHidden;
649        }
650
651        /**
652         * Sets is metadata template field hidden.
653         * @param isHidden is metadata template field hidden?
654         */
655        public void setIsHidden(boolean isHidden) {
656            this.isHidden = isHidden;
657        }
658
659        /**
660         * Gets the description of the field.
661         * @return the description of the field.
662         */
663        public String getDescription() {
664            return this.description;
665        }
666
667        /**
668         * Sets the description of the field.
669         * @param description the description of the field.
670         */
671        public void setDescription(String description) {
672            this.description = description;
673        }
674
675        /**
676         * Gets list of possible options for enum type of the field.
677         * @return list of possible options for enum type of the field.
678         */
679        public List<String> getOptions() {
680            return this.options;
681        }
682
683        /**
684         * Sets list of possible options for enum type of the field.
685         * @param options list of possible options for enum type of the field.
686         */
687        public void setOptions(List<String> options) {
688            this.options = options;
689        }
690
691        /**
692         * {@inheritDoc}
693         */
694        @Override
695        void parseJSONMember(JsonObject.Member member) {
696            JsonValue value = member.getValue();
697            String memberName = member.getName();
698            if (memberName.equals("type")) {
699                this.type = value.asString();
700            } else if (memberName.equals("key")) {
701                this.key = value.asString();
702            } else if (memberName.equals("displayName")) {
703                this.displayName = value.asString();
704            } else if (memberName.equals("hidden")) {
705                this.isHidden = value.asBoolean();
706            } else if (memberName.equals("description")) {
707                this.description = value.asString();
708            } else if (memberName.equals("options")) {
709                this.options = new ArrayList<String>();
710                for (JsonValue key: value.asArray()) {
711                    this.options.add(key.asObject().get("key").asString());
712                }
713            } else if (memberName.equals("id")) {
714                this.id = value.asString();
715            }
716        }
717    }
718
719    /**
720     * Posssible operations that can be performed in a Metadata template.
721     *  <ul>
722     *      <li>Add an enum option</li>
723     *      <li>Edit an enum option</li>
724     *      <li>Remove an enum option</li>
725     *      <li>Add a field</li>
726     *      <li>Edit a field</li>
727     *      <li>Remove a field</li>
728     *      <li>Edit template</li>
729     *      <li>Reorder the enum option</li>
730     *      <li>Reorder the field list</li>
731     *  </ul>
732     */
733    public static class FieldOperation extends BoxJSONObject {
734
735        private Operation op;
736        private Field data;
737        private String fieldKey;
738        private List<String> fieldKeys;
739        private List<String> enumOptionKeys;
740        private String enumOptionKey;
741        private String multiSelectOptionKey;
742        private List<String> multiSelectOptionKeys;
743
744        /**
745         * Constructs an empty FieldOperation.
746         */
747        public FieldOperation() {
748            super();
749        }
750
751        /**
752         * Constructs a Field operation from a JSON string.
753         * @param json the json encoded metadate template field.
754         */
755        public FieldOperation(String json) {
756            super(json);
757        }
758
759        /**
760         * Constructs a Field operation from a JSON object.
761         * @param jsonObject the json encoded metadate template field.
762         */
763        FieldOperation(JsonObject jsonObject) {
764            super(jsonObject);
765        }
766
767        /**
768         * Gets the operation.
769         * @return the operation
770         */
771        public Operation getOp() {
772            return this.op;
773        }
774
775        /**
776         * Gets the data associated with the operation.
777         * @return the field object representing the data
778         */
779        public Field getData() {
780            return this.data;
781        }
782
783        /**
784         * Gets the field key.
785         * @return the field key
786         */
787        public String getFieldKey() {
788            return this.fieldKey;
789        }
790
791        /**
792         * Gets the list of field keys.
793         * @return the list of Strings
794         */
795        public List<String> getFieldKeys() {
796            return this.fieldKeys;
797        }
798
799        /**
800         * Gets the list of keys of the Enum options.
801         * @return the list of Strings
802         */
803        public List<String> getEnumOptionKeys() {
804            return this.enumOptionKeys;
805        }
806
807        /**
808         * Sets the operation.
809         * @param op the operation
810         */
811        public void setOp(Operation op) {
812            this.op = op;
813        }
814
815        /**
816         * Sets the data.
817         * @param data the Field object representing the data
818         */
819        public void setData(Field data) {
820            this.data = data;
821        }
822
823        /**
824         * Sets the field key.
825         * @param fieldKey the key of the field
826         */
827        public void setFieldKey(String fieldKey) {
828            this.fieldKey = fieldKey;
829        }
830
831        /**
832         * Sets the list of the field keys.
833         * @param fieldKeys the list of strings
834         */
835        public void setFieldKeys(List<String> fieldKeys) {
836            this.fieldKeys = fieldKeys;
837        }
838
839        /**
840         * Sets the list of the enum option keys.
841         * @param enumOptionKeys the list of Strings
842         */
843        public void setEnumOptionKeys(List<String> enumOptionKeys) {
844            this.enumOptionKeys = enumOptionKeys;
845        }
846
847        /**
848         * Gets the enum option key.
849         * @return the enum option key
850         */
851        public String getEnumOptionKey() {
852            return this.enumOptionKey;
853        }
854
855        /**
856         * Sets the enum option key.
857         * @param enumOptionKey the enum option key
858         */
859        public void setEnumOptionKey(String enumOptionKey) {
860            this.enumOptionKey = enumOptionKey;
861        }
862
863        /**
864         * Gets the multi-select option key.
865         * @return the key.
866         */
867        public String getMultiSelectOptionKey() {
868            return this.multiSelectOptionKey;
869        }
870
871        /**
872         * Sets the multi-select option key.
873         * @param key the key.
874         */
875        public void setMultiSelectOptionKey(String key) {
876            this.multiSelectOptionKey = key;
877        }
878
879        /**
880         * Gets the list of multiselect option keys.
881         * @return the list of keys.
882         */
883        public List<String> getMultiSelectOptionKeys() {
884            return this.multiSelectOptionKeys;
885        }
886
887        /**
888         * Sets the multi-select option keys.
889         * @param keys the list of keys.
890         */
891        public void setMultiSelectOptionKeys(List<String> keys) {
892            this.multiSelectOptionKeys = keys;
893        }
894
895        /**
896         * {@inheritDoc}
897         */
898        @Override
899        void parseJSONMember(JsonObject.Member member) {
900            JsonValue value = member.getValue();
901            String memberName = member.getName();
902            if (memberName.equals("op")) {
903                this.op = Operation.valueOf(value.asString());
904            } else if (memberName.equals("data")) {
905                this.data = new Field(value.asObject());
906            } else if (memberName.equals("fieldKey")) {
907                this.fieldKey = value.asString();
908            } else if (memberName.equals("fieldKeys")) {
909                if (this.fieldKeys == null) {
910                    this.fieldKeys = new ArrayList<String>();
911                } else {
912                    this.fieldKeys.clear();
913                }
914
915                JsonArray array = value.asArray();
916                for (JsonValue jsonValue: array) {
917                    this.fieldKeys.add(jsonValue.asString());
918                }
919            } else if (memberName.equals("enumOptionKeys")) {
920                if (this.enumOptionKeys == null) {
921                    this.enumOptionKeys = new ArrayList<String>();
922                } else {
923                    this.enumOptionKeys.clear();
924                }
925
926                JsonArray array = value.asArray();
927                for (JsonValue jsonValue: array) {
928                    this.enumOptionKeys.add(jsonValue.asString());
929                }
930            } else if (memberName.equals("enumOptionKey")) {
931                this.enumOptionKey = value.asString();
932            } else if (memberName.equals("multiSelectOptionKey")) {
933                this.multiSelectOptionKey = value.asString();
934            } else if (memberName.equals("multiSelectOptionKeys")) {
935                this.multiSelectOptionKeys = new ArrayList<String>();
936                for (JsonValue key : value.asArray()) {
937                    this.multiSelectOptionKeys.add(key.asString());
938                }
939            }
940        }
941    }
942
943    /**
944     * Possible template operations.
945     */
946    public enum Operation {
947
948        /**
949         * Adds an enum option at the end of the enum option list for the specified field.
950         */
951        addEnumOption,
952
953        /**
954         * Edits the enum option.
955         */
956        editEnumOption,
957
958        /**
959         * Removes the specified enum option from the specified enum field.
960         */
961        removeEnumOption,
962
963        /**
964         * Adds a field at the end of the field list for the template.
965         */
966        addField,
967
968        /**
969         * Edits any number of the base properties of a field: displayName, hidden, description.
970         */
971        editField,
972
973        /**
974         * Removes the specified field from the template.
975         */
976        removeField,
977
978        /**
979         * Edits any number of the base properties of a template: displayName, hidden.
980         */
981        editTemplate,
982
983        /**
984         * Reorders the enum option list to match the requested enum option list.
985         */
986        reorderEnumOptions,
987
988        /**
989         * Reorders the field list to match the requested field list.
990         */
991        reorderFields,
992
993        /**
994         * Adds a new option to a multiselect field.
995         */
996        addMultiSelectOption,
997
998        /**
999         * Edits an existing option in a multiselect field.
1000         */
1001        editMultiSelectOption,
1002
1003        /**
1004         * Removes an option from a multiselect field.
1005         */
1006        removeMultiSelectOption,
1007
1008        /**
1009         * Changes the display order of options in a multiselect field.
1010         */
1011        reorderMultiSelectOptions
1012    }
1013}