001/*
002 *   Copyright 2020 Vonage
003 *
004 *   Licensed under the Apache License, Version 2.0 (the "License");
005 *   you may not use this file except in compliance with the License.
006 *   You may obtain a copy of the License at
007 *
008 *        http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *   Unless required by applicable law or agreed to in writing, software
011 *   distributed under the License is distributed on an "AS IS" BASIS,
012 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *   See the License for the specific language governing permissions and
014 *   limitations under the License.
015 */
016package com.vonage.client.application;
017
018import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
019import com.fasterxml.jackson.annotation.JsonInclude;
020import com.fasterxml.jackson.annotation.JsonProperty;
021import com.fasterxml.jackson.core.JsonProcessingException;
022import com.fasterxml.jackson.databind.ObjectMapper;
023import com.vonage.client.VonageUnexpectedException;
024import com.vonage.client.application.capabilities.*;
025
026import java.io.IOException;
027
028@JsonIgnoreProperties(ignoreUnknown = true)
029@JsonInclude(JsonInclude.Include.NON_NULL)
030public class Application {
031    private String id;
032    private String name;
033    private Keys keys;
034    private Capabilities capabilities;
035
036    private Application() {
037
038    }
039
040    private Application(Builder builder) {
041        this.id = builder.id;
042        this.name = builder.name;
043        this.keys = builder.keys;
044        this.capabilities = builder.capabilities;
045    }
046
047    public String getId() {
048        return id;
049    }
050
051    public String getName() {
052        return name;
053    }
054
055    public Keys getKeys() {
056        return keys;
057    }
058
059    public Capabilities getCapabilities() {
060        return capabilities;
061    }
062
063    public String toJson() {
064        try {
065            return new ObjectMapper().writeValueAsString(this);
066        } catch (JsonProcessingException jpe) {
067            throw new VonageUnexpectedException("Failed to produce json from Application object.", jpe);
068        }
069    }
070
071    /**
072     * @return A new Builder to start building.
073     */
074    public static Builder builder() {
075        return new Builder();
076    }
077
078    /**
079     * Copy an application to a new builder to modify into a new application object.
080     *
081     * @param application An existing application to modify.
082     *
083     * @return A new Builder to start building.
084     */
085    public static Builder builder(Application application) {
086        return new Builder(application);
087    }
088
089    public static Application fromJson(String json) {
090        try {
091            return new ObjectMapper().readValue(json, Application.class);
092        } catch (IOException e) {
093            throw new VonageUnexpectedException("Failed to produce Application from json.", e);
094        }
095    }
096
097    public static class Builder {
098        private String id;
099        private String name;
100        private Keys keys;
101        private Capabilities capabilities;
102
103        public Builder() {
104
105        }
106
107        public Builder(Application application) {
108            this.id = application.id;
109            this.name = application.name;
110            this.keys = application.keys;
111            this.capabilities = application.capabilities;
112        }
113
114        /**
115         * @param name The name of the application.
116         *
117         * @return The {@link Builder} to keep building.
118         */
119        public Builder name(String name) {
120            this.name = name;
121            return this;
122        }
123
124        /**
125         * @param publicKey The public key for use with the application.
126         *
127         * @return The {@link Builder} to keep building.
128         */
129        public Builder publicKey(String publicKey) {
130            this.keys = new Keys();
131            this.keys.publicKey = publicKey;
132            return this;
133        }
134
135        /**
136         * Add a capability for the application. Each capability can only be used one time. Adding a capability of a
137         * duplicate type will overwrite the previous capability of that type.
138         *
139         * @param capability The capability to add to it.
140         *
141         * @return The {@link Builder} to keep building.
142         */
143        public Builder addCapability(Capability capability) {
144            if (this.capabilities == null) {
145                this.capabilities = new Capabilities();
146            }
147
148            this.capabilities.setCapability(capability);
149
150            return this;
151        }
152
153        /**
154         * Remove a capability from the application.
155         *
156         * @param type The type of capability to remove.
157         *
158         * @return The {@link Builder} to keep building.
159         */
160        public Builder removeCapability(Capability.Type type) {
161            if (this.capabilities == null) {
162                this.capabilities = new Capabilities();
163            }
164
165            this.capabilities.setCapability(type, null);
166            this.capabilities = shouldBeDeleted(this.capabilities) ? null : this.capabilities;
167            return this;
168        }
169
170        /**
171         * @return A new Application containing the configured properties.
172         */
173        public Application build() {
174            return new Application(this);
175        }
176
177        private boolean shouldBeDeleted(Capabilities capabilities) {
178            return (capabilities.voice == null
179                    && capabilities.rtc == null
180                    && capabilities.messages == null
181                    && capabilities.vbc == null);
182        }
183    }
184
185    @JsonIgnoreProperties(ignoreUnknown = true)
186    @JsonInclude(JsonInclude.Include.NON_NULL)
187    public static class Keys {
188        @JsonProperty("public_key")
189        private String publicKey;
190        @JsonProperty("private_key")
191        private String privateKey;
192
193        public String getPublicKey() {
194            return publicKey;
195        }
196
197        public String getPrivateKey() {
198            return privateKey;
199        }
200    }
201
202    @JsonIgnoreProperties(ignoreUnknown = true)
203    @JsonInclude(JsonInclude.Include.NON_NULL)
204    public static class Capabilities {
205        private Voice voice;
206        private Messages messages;
207        private Rtc rtc;
208        private Vbc vbc;
209
210        public Voice getVoice() {
211            return voice;
212        }
213
214        public Messages getMessages() {
215            return messages;
216        }
217
218        public Rtc getRtc() {
219            return rtc;
220        }
221
222        public Vbc getVbc() {
223            return vbc;
224        }
225
226        private void setCapability(Capability.Type type, Capability capability) {
227            switch (type) {
228                case VOICE:
229                    this.voice = (Voice) capability;
230                    break;
231                case MESSAGES:
232                    this.messages = (Messages) capability;
233                    break;
234                case RTC:
235                    this.rtc = (Rtc) capability;
236                    break;
237                case VBC:
238                    this.vbc = (Vbc) capability;
239                    break;
240            }
241        }
242
243        private void setCapability(Capability capability) {
244            setCapability(capability.getType(), capability);
245        }
246    }
247}