1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.forgerock.api.models;
17
18 import static org.forgerock.api.models.Definitions.definitions;
19 import static org.forgerock.api.models.Errors.errors;
20 import static org.forgerock.api.models.Paths.paths;
21 import static org.forgerock.api.models.Services.services;
22 import static org.forgerock.api.util.ValidationUtil.isEmpty;
23
24 import java.util.Objects;
25
26 import com.fasterxml.jackson.annotation.JsonInclude;
27 import com.fasterxml.jackson.annotation.JsonProperty;
28 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
29 import org.forgerock.api.ApiValidationException;
30 import org.forgerock.util.i18n.LocalizableString;
31
32
33 @JsonDeserialize(builder = ApiDescription.Builder.class)
34 @JsonInclude(JsonInclude.Include.NON_NULL)
35 public final class ApiDescription {
36
37 private final String id;
38 private final String version;
39 private final LocalizableString description;
40 private final Definitions definitions;
41 private final Services services;
42 private final Errors errors;
43 private final Paths paths;
44
45 private ApiDescription(Builder builder) {
46 this.id = builder.id;
47 this.version = builder.version;
48 this.description = builder.description;
49 this.definitions = builder.definitions == null ? definitions().build() : builder.definitions;
50 this.services = builder.services == null ? services().build() : builder.services;
51 this.errors = builder.errors == null ? errors().build() : builder.errors;
52 this.paths = builder.paths == null ? paths().build() : builder.paths;
53
54 if (isEmpty(id) || isEmpty(version)) {
55 throw new ApiValidationException("id and version required");
56 }
57 }
58
59
60
61
62
63
64 public String getId() {
65 return id;
66 }
67
68
69
70
71
72
73 public String getVersion() {
74 return version;
75 }
76
77
78
79
80
81
82 public LocalizableString getDescription() {
83 return description;
84 }
85
86
87
88
89
90
91 public Definitions getDefinitions() {
92 return definitions.getDefinitions().isEmpty() ? null : definitions;
93 }
94
95
96
97
98
99
100
101
102
103 void addDefinition(String id, Schema schema) {
104 if (schema.getReference() != null) {
105 throw new IllegalArgumentException("Cannot define a schema using a reference");
106 }
107 Schema defined = definitions.get(id);
108 if (defined != null && !defined.equals(schema)) {
109 throw new IllegalArgumentException("Trying to redefine already defined schema, " + id);
110 }
111 definitions.getDefinitions().put(id, schema);
112 }
113
114
115
116
117
118
119 public Services getServices() {
120 return services.getServices().isEmpty() ? null : services;
121 }
122
123
124
125
126
127
128
129
130
131
132 void addService(String id, Resource resource) {
133 if (resource.getReference() != null) {
134 throw new IllegalArgumentException("Cannot define a resource using a reference");
135 }
136 Resource defined = services.get(id);
137 if (defined != null && !defined.equals(resource)) {
138 throw new IllegalArgumentException("Trying to redefine already defined resource, " + id);
139 }
140 services.getServices().put(id, resource);
141 }
142
143
144
145
146
147
148 public Errors getErrors() {
149 return errors.getErrors().isEmpty() ? null : errors;
150 }
151
152
153
154
155
156
157
158
159
160
161 void addError(String id, ApiError apiError) {
162 if (apiError.getReference() != null) {
163 throw new IllegalArgumentException("Cannot define an apiError using a reference");
164 }
165 ApiError defined = errors.get(id);
166 if (defined != null && !defined.equals(apiError)) {
167 throw new IllegalArgumentException("Trying to redefine already defined apiError, " + id);
168 }
169 errors.getErrors().put(id, apiError);
170 }
171
172
173
174
175
176
177
178 @JsonInclude(JsonInclude.Include.NON_EMPTY)
179 public Paths getPaths() {
180 return paths;
181 }
182
183
184
185
186
187
188 public static Builder apiDescription() {
189 return new Builder();
190 }
191
192 @Override
193 public boolean equals(Object o) {
194 if (this == o) {
195 return true;
196 }
197 if (o == null || getClass() != o.getClass()) {
198 return false;
199 }
200 ApiDescription that = (ApiDescription) o;
201 return Objects.equals(id, that.id)
202 && Objects.equals(version, that.version)
203 && Objects.equals(description, that.description)
204 && Objects.equals(definitions, that.definitions)
205 && Objects.equals(services, that.services)
206 && Objects.equals(errors, that.errors)
207 && Objects.equals(paths, that.paths);
208 }
209
210 @Override
211 public int hashCode() {
212 return Objects.hash(id, version, description, definitions, services, errors, paths);
213 }
214
215
216
217
218 public static final class Builder {
219
220 private String id;
221 private LocalizableString description;
222 private Definitions definitions;
223 private Errors errors;
224 private Services services;
225 private Paths paths;
226 private String version;
227
228
229
230
231 private Builder() {
232 }
233
234
235
236
237
238
239
240 @JsonProperty("id")
241 public Builder id(String id) {
242 this.id = id;
243 return this;
244 }
245
246
247
248
249
250
251
252 @JsonProperty("description")
253 public Builder description(String description) {
254 this.description = new LocalizableString(description);
255 return this;
256 }
257
258
259
260
261
262
263
264 public Builder description(LocalizableString description) {
265 this.description = description;
266 return this;
267 }
268
269
270
271
272
273
274
275 @JsonProperty("definitions")
276 public Builder definitions(Definitions definitions) {
277 this.definitions = definitions;
278 return this;
279 }
280
281
282
283
284
285
286
287
288 @JsonProperty("services")
289 public Builder services(Services services) {
290 this.services = services;
291 return this;
292 }
293
294
295
296
297
298
299
300 @JsonProperty("errors")
301 public Builder errors(Errors errors) {
302 this.errors = errors;
303 return this;
304 }
305
306
307
308
309
310
311
312 @JsonProperty("paths")
313 public Builder paths(Paths paths) {
314 this.paths = paths;
315 return this;
316 }
317
318
319
320
321
322
323
324 @JsonProperty("version")
325 public Builder version(String version) {
326 this.version = version;
327 return this;
328 }
329
330
331
332
333
334
335 public ApiDescription build() {
336 return new ApiDescription(this);
337 }
338 }
339 }
340