001package com.box.sdk;
002
003import com.eclipsesource.json.Json;
004import com.eclipsesource.json.JsonObject;
005import com.eclipsesource.json.JsonValue;
006import java.net.URL;
007import java.util.ArrayList;
008import java.util.List;
009
010
011/**
012 * Represents a Sign Template used in the Box Sign API.
013 *
014 * @see <a href="https://developer.box.com/reference/resources/sign-templates/">Box Sign Templates</a>
015 *
016 * <p>Unless otherwise noted, the methods in this class can throw an unchecked {@link BoxAPIException} (unchecked
017 * meaning that the compiler won't force you to handle it) if an error occurs. If you wish to implement custom error
018 * handling for errors related to the Box REST API, you should capture this exception explicitly.</p>
019 */
020@BoxResourceType("sign_template")
021public class BoxSignTemplate extends BoxResource {
022
023    /**
024     * The URL template for Sign Templates.
025     */
026    public static final URLTemplate SIGN_TEMPLATES_URL_TEMPLATE = new URLTemplate("sign_templates");
027
028    /**
029     * The URL template for Sign Templates operations with a given ID.
030     */
031    public static final URLTemplate SIGN_TEMPLATE_URL_TEMPLATE = new URLTemplate("sign_templates/%s");
032
033    /**
034     * The default limit of entries per response.
035     */
036    public static final int DEFAULT_LIMIT = 100;
037
038    /**
039     * Constructs a BoxSignTemplate for a resource with a given ID.
040     *
041     * @param api the API connection to be used by the resource.
042     * @param id  the ID of the resource.
043     */
044    public BoxSignTemplate(BoxAPIConnection api, String id) {
045        super(api, id);
046    }
047
048    /**
049     * Return all Sign Templates.
050     *
051     * @param api the API connection to be used by the resource.
052     * @return an iterable with all Sign Templates.
053     */
054    public static Iterable<BoxSignTemplate.Info> getAll(BoxAPIConnection api) {
055        return getAll(api, DEFAULT_LIMIT);
056    }
057
058    /**
059     * Return all Sign Templates.
060     *
061     * @param api   the API connection to be used by the resource.
062     * @param limit the limit of entries per response.
063     * @return an iterable with all Sign Templates.
064     */
065    public static Iterable<BoxSignTemplate.Info> getAll(BoxAPIConnection api, int limit) {
066        QueryStringBuilder builder = new QueryStringBuilder();
067        URL url = SIGN_TEMPLATES_URL_TEMPLATE.buildWithQuery(api.getBaseURL(), builder.toString());
068        return new BoxResourceIterable<BoxSignTemplate.Info>(api, url, limit) {
069
070            @Override
071            protected BoxSignTemplate.Info factory(JsonObject jsonObject) {
072                BoxSignTemplate template = new BoxSignTemplate(api, jsonObject.get("id").asString());
073                return template.new Info(jsonObject);
074            }
075        };
076
077    }
078
079    /**
080     * Return information about this Sign Template.
081     *
082     * @return information about this Sign Template.
083     */
084    public BoxSignTemplate.Info getInfo() {
085        URL url = SIGN_TEMPLATE_URL_TEMPLATE.buildAlpha(this.getAPI().getBaseURL(), this.getID());
086        BoxAPIRequest request = new BoxAPIRequest(this.getAPI(), url, "GET");
087        try (BoxJSONResponse response = (BoxJSONResponse) request.send()) {
088            JsonObject jsonObject = Json.parse(response.getJSON()).asObject();
089            return new Info(jsonObject);
090        }
091    }
092
093    /**
094     * Contains information about a BoxSignTemplate.
095     */
096    public class Info extends BoxResource.Info {
097
098        private BoxSignTemplateAdditionalInfo additionalInfo;
099        private boolean areEmailSettingsLocked;
100        private boolean areFieldsLocked;
101        private boolean areOptionsLocked;
102        private boolean areFilesLocked;
103        private boolean areRecipientsLocked;
104        private BoxSignTemplateCustomBranding customBranding;
105        private Integer daysValid;
106        private String emailMessage;
107        private String emailSubject;
108        private String name;
109        private BoxFolder.Info parentFolder;
110        private BoxSignTemplateReadySignLink readySignLink;
111        private List<BoxSignTemplateSigner> signers;
112        private List<BoxFile.Info> sourceFiles;
113
114        /**
115         * Constructs an empty Info object.
116         */
117        public Info() {
118            super();
119        }
120
121        /**
122         * Constructs an Info object with the provided JSON string.
123         *
124         * @param json the JSON string representing the Sign Template.
125         */
126        public Info(String json) {
127            super(json);
128        }
129
130        /**
131         * Constructs an Info object with the provided JSON object.
132         *
133         * @param jsonObject the JSON object representing the Sign Template.
134         */
135        Info(JsonObject jsonObject) {
136            super(jsonObject);
137        }
138
139        /**
140         * {@inheritDoc}
141         */
142        @Override
143        public BoxSignTemplate getResource() {
144            return BoxSignTemplate.this;
145        }
146
147        /**
148         * Gets the additional information about this Sign Template.
149         *
150         * @return the additional information about this Sign Template.
151         */
152        public BoxSignTemplateAdditionalInfo getAdditionalInfo() {
153            return this.additionalInfo;
154        }
155
156        /**
157         * Gets whether the templates email settings are editable or not.
158         *
159         * @return true if the email settings are locked; otherwise false.
160         */
161        public boolean getAreEmailSettingsLocked() {
162            return this.areEmailSettingsLocked;
163        }
164
165        /**
166         * Gets whether the templates input fields are editable or not.
167         * This includes deleting or renaming template files.
168         *
169         * @return true if the fields are locked; otherwise false.
170         */
171        public boolean getAreFieldsLocked() {
172            return this.areFieldsLocked;
173        }
174
175        /**
176         * Gets weather the templates input options are editable or not.
177         *
178         * @return true if the options are editable; otherwise false.
179         */
180        public boolean getAreOptionsLocked() {
181            return this.areOptionsLocked;
182        }
183
184        /**
185         * Gets whether the template document options are editable or not,
186         * for example renaming the document.
187         *
188         * @return true if the files are locked; otherwise false.
189         */
190        public boolean getAreFilesLocked() {
191            return this.areFilesLocked;
192        }
193
194        /**
195         * Gets whether the template signers are editable or not.
196         *
197         * @return true if the recipients are locked; otherwise false.
198         */
199        public boolean getAreRecipientsLocked() {
200            return this.areRecipientsLocked;
201        }
202
203        /**
204         * Gets the custom branding applied to notifications and signature requests.
205         *
206         * @return the custom branding for this Sign Template.
207         */
208        public BoxSignTemplateCustomBranding getCustomBranding() {
209            return this.customBranding;
210        }
211
212        /**
213         * Gets the number of days after which the created signature request
214         * will automatically expire if not completed.
215         * By default, we do not apply any expiration date on signature requests,
216         * and the signature request does not expire.
217         *
218         * @return the number of days the template is valid for.
219         */
220        public Integer getDaysValid() {
221            return this.daysValid;
222        }
223
224        /**
225         * Gets the email message that will be sent to all signers.
226         *
227         * @return the email message for this Sign Template.
228         */
229        public String getEmailMessage() {
230            return this.emailMessage;
231        }
232
233        /**
234         * Gets the email subject that will be sent to all signers.
235         *
236         * @return the email subject for this Sign Template.
237         */
238        public String getEmailSubject() {
239            return this.emailSubject;
240        }
241
242        /**
243         * Gets the name of this Sign Template.
244         *
245         * @return the name of this Sign Template.
246         */
247        public String getName() {
248            return this.name;
249        }
250
251        /**
252         * Gets the parent folder of this Sign Template.
253         *
254         * @return the parent folder of this Sign Template.
255         */
256        public BoxFolder.Info getParentFolder() {
257            return this.parentFolder;
258        }
259
260        /**
261         * Gets the ready sign link for this Sign Template.
262         *
263         * @return the ready sign link for this Sign Template.
264         */
265        public BoxSignTemplateReadySignLink getReadySignLink() {
266            return this.readySignLink;
267        }
268
269        /**
270         * Gets the signers for this Sign Template.
271         *
272         * @return the signers for this Sign Template.
273         */
274        public List<BoxSignTemplateSigner> getSigners() {
275            return this.signers;
276        }
277
278        /**
279         * Gets the source files for this Sign Template.
280         *
281         * @return the source files for this Sign Template.
282         */
283        public List<BoxFile.Info> getSourceFiles() {
284            return this.sourceFiles;
285        }
286
287        /**
288         * {@inheritDoc}
289         */
290        @Override
291        void parseJSONMember(JsonObject.Member member) {
292            super.parseJSONMember(member);
293            String memberName = member.getName();
294            JsonValue value = member.getValue();
295            try {
296                switch (memberName) {
297                    case "additional_info":
298                        this.additionalInfo = this.parseAdditionalInfo(value.asObject());
299                        break;
300                    case "are_email_settings_locked":
301                        this.areEmailSettingsLocked = value.asBoolean();
302                        break;
303                    case "are_fields_locked":
304                        this.areFieldsLocked = value.asBoolean();
305                        break;
306                    case "are_options_locked":
307                        this.areOptionsLocked = value.asBoolean();
308                        break;
309                    case "are_files_locked":
310                        this.areFilesLocked = value.asBoolean();
311                        break;
312                    case "are_recipients_locked":
313                        this.areRecipientsLocked = value.asBoolean();
314                        break;
315                    case "custom_branding":
316                        this.customBranding = this.parseCustomBranding(value.asObject());
317                        break;
318                    case "days_valid":
319                        this.daysValid = value.asInt();
320                        break;
321                    case "email_message":
322                        this.emailMessage = value.asString();
323                        break;
324                    case "email_subject":
325                        this.emailSubject = value.asString();
326                        break;
327                    case "name":
328                        this.name = value.asString();
329                        break;
330                    case "parent_folder":
331                        JsonObject parentFolderJSON = value.asObject();
332                        String parentFolderID = parentFolderJSON.get("id").asString();
333                        BoxFolder parentFolder = new BoxFolder(getAPI(), parentFolderID);
334                        this.parentFolder = parentFolder.new Info(parentFolderJSON);
335                        break;
336                    case "ready_sign_link":
337                        this.readySignLink = this.parseReadySignLink(value.asObject());
338                        break;
339                    case "signers":
340                        this.signers = this.parseSigners(value.asArray());
341                        break;
342                    case "source_files":
343                        this.sourceFiles = this.parseSourceFiles(value.asArray());
344                        break;
345                    default:
346                }
347            } catch (Exception e) {
348                throw new BoxDeserializationException(memberName, value.toString(), e);
349            }
350        }
351
352        private BoxSignTemplateAdditionalInfo parseAdditionalInfo(JsonValue additionalInfoJSON) {
353            List<String> nonEditableFields = new ArrayList<String>();
354            for (JsonValue fieldJSON : additionalInfoJSON.asObject().get("non_editable").asArray()) {
355                nonEditableFields.add(fieldJSON.asString());
356            }
357            BoxSignTemplateAdditionalInfoRequired required = this.parseAdditionalInfoRequired(
358                additionalInfoJSON.asObject().get("required").asObject()
359            );
360            return new BoxSignTemplateAdditionalInfo(nonEditableFields, required);
361        }
362
363        private BoxSignTemplateAdditionalInfoRequired parseAdditionalInfoRequired(JsonObject requiredJSON) {
364            List<List<String>> signers = new ArrayList<List<String>>();
365            for (JsonValue signerJSON : requiredJSON.get("signers").asArray()) {
366                List<String> signer = new ArrayList<String>();
367                for (JsonValue fieldJSON : signerJSON.asArray()) {
368                    signer.add(fieldJSON.asString());
369                }
370                signers.add(signer);
371            }
372            return new BoxSignTemplateAdditionalInfoRequired(signers);
373        }
374
375        private List<BoxFile.Info> parseSourceFiles(JsonValue filesArray) {
376            List<BoxFile.Info> files = new ArrayList<BoxFile.Info>();
377            for (JsonValue fileJSON : filesArray.asArray()) {
378                JsonObject fileObj = fileJSON.asObject();
379                String fileID = fileObj.get("id").asString();
380                BoxFile file = new BoxFile(getAPI(), fileID);
381                files.add(file.new Info(fileObj));
382            }
383            return files;
384        }
385
386        private List<BoxSignTemplateSigner> parseSigners(JsonValue signersArray) {
387            List<BoxSignTemplateSigner> signers = new ArrayList<BoxSignTemplateSigner>();
388            for (JsonValue signerJSON : signersArray.asArray()) {
389                JsonObject signerObj = signerJSON.asObject();
390                signers.add(new BoxSignTemplateSigner(signerObj, getAPI()));
391            }
392            return signers;
393        }
394
395        private BoxSignTemplateCustomBranding parseCustomBranding(JsonObject customBrandingJSON) {
396            String brandingColor = customBrandingJSON.get("branding_color").asString();
397            String companyName = customBrandingJSON.get("company_name").asString();
398            String emailFooterText = customBrandingJSON.get("email_footer_text").asString();
399            String logoUri = customBrandingJSON.get("logo_uri").asString();
400            return new BoxSignTemplateCustomBranding(brandingColor, companyName, emailFooterText, logoUri);
401        }
402
403        private BoxSignTemplateReadySignLink parseReadySignLink(JsonObject readySignLinkJSON) {
404            String folderID = readySignLinkJSON.get("folder_id").asString();
405            String instructions = readySignLinkJSON.get("instructions").asString();
406            boolean isActive = readySignLinkJSON.get("is_active").asBoolean();
407            boolean isNofiticationDisabled = readySignLinkJSON.get("is_notification_disabled").asBoolean();
408            String name = readySignLinkJSON.get("name").asString();
409            String url = readySignLinkJSON.get("url").asString();
410            return new BoxSignTemplateReadySignLink(folderID, instructions, isActive,
411                isNofiticationDisabled, name, url);
412        }
413    }
414}