1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.juneau.bean.openapi3;
18
19 import static org.apache.juneau.commons.utils.AssertionUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.apache.juneau.commons.utils.Utils.*;
22 import static org.apache.juneau.internal.ConverterUtils.*;
23
24 import java.util.*;
25
26 import org.apache.juneau.commons.collections.*;
27
28 /**
29 * Provides metadata about the API.
30 *
31 * <p>
32 * The Info Object contains required and optional metadata about the API, including the title, version, description,
33 * terms of service, contact information, and license. This metadata can be used by client tooling and is typically
34 * displayed in API documentation interfaces.
35 *
36 * <h5 class='section'>OpenAPI Specification:</h5>
37 * <p>
38 * The Info Object is composed of the following fields:
39 * <ul class='spaced-list'>
40 * <li><c>title</c> (string, REQUIRED) - The title of the API
41 * <li><c>version</c> (string, REQUIRED) - The version of the OpenAPI document (not the API itself)
42 * <li><c>description</c> (string) - A short description of the API (CommonMark syntax may be used)
43 * <li><c>termsOfService</c> (string) - A URL to the Terms of Service for the API
44 * <li><c>contact</c> ({@link Contact}) - Contact information for the exposed API
45 * <li><c>license</c> ({@link License}) - License information for the exposed API
46 * </ul>
47 *
48 * <h5 class='section'>Example:</h5>
49 * <p class='bjava'>
50 * <jc>// Create an Info object</jc>
51 * Info <jv>info</jv> = <jk>new</jk> Info()
52 * .setTitle(<js>"Pet Store API"</js>)
53 * .setVersion(<js>"1.0.0"</js>)
54 * .setDescription(<js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>)
55 * .setTermsOfService(<js>"http://example.com/terms/"</js>)
56 * .setContact(
57 * <jk>new</jk> Contact()
58 * .setName(<js>"API Support"</js>)
59 * .setUrl(URI.<jsm>create</jsm>(<js>"http://www.example.com/support"</js>))
60 * .setEmail(<js>"support@example.com"</js>)
61 * )
62 * .setLicense(
63 * <jk>new</jk> License()
64 * .setName(<js>"Apache 2.0"</js>)
65 * .setUrl(URI.<jsm>create</jsm>(<js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>))
66 * );
67 * </p>
68 * <p class='bjava'>
69 * <jc>// Serialize to JSON</jc>
70 * String <jv>json</jv> = Json.<jsm>from</jsm>(<jv>info</jv>);
71 *
72 * <jc>// Or just use toString() which does the same as above.</jc>
73 * <jv>json</jv> = <jv>info</jv>.toString();
74 * </p>
75 * <p class='bcode'>
76 * <jc>// Output</jc>
77 * {
78 * <js>"title"</js>: <js>"Pet Store API"</js>,
79 * <js>"version"</js>: <js>"1.0.0"</js>,
80 * <js>"description"</js>: <js>"This is a sample Pet Store Server based on the OpenAPI 3.0 specification."</js>,
81 * <js>"termsOfService"</js>: <js>"http://example.com/terms/"</js>,
82 * <js>"contact"</js>: {
83 * <js>"name"</js>: <js>"API Support"</js>,
84 * <js>"url"</js>: <js>"http://www.example.com/support"</js>,
85 * <js>"email"</js>: <js>"support@example.com"</js>
86 * },
87 * <js>"license"</js>: {
88 * <js>"name"</js>: <js>"Apache 2.0"</js>,
89 * <js>"url"</js>: <js>"http://www.apache.org/licenses/LICENSE-2.0.html"</js>
90 * },
91 * <js>"version"</js>: <js>"1.0.1"</js>
92 * }
93 * </p>
94 *
95 * <h5 class='section'>See Also:</h5><ul>
96 * <li class='link'><a class="doclink" href="https://spec.openapis.org/oas/v3.0.0#info-object">OpenAPI Specification > Info Object</a>
97 * <li class='link'><a class="doclink" href="https://swagger.io/docs/specification/api-general-info/">OpenAPI API General Info</a>
98 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauBeanOpenApi3">juneau-bean-openapi-v3</a>
99 * </ul>
100 */
101 public class Info extends OpenApiElement {
102
103 private String title, description, termsOfService, version;
104 private Contact contact;
105 private License license;
106
107 /**
108 * Default constructor.
109 */
110 public Info() {}
111
112 /**
113 * Copy constructor.
114 *
115 * @param copyFrom The object to copy.
116 */
117 public Info(Info copyFrom) {
118 super(copyFrom);
119
120 this.title = copyFrom.title;
121 this.description = copyFrom.description;
122 this.termsOfService = copyFrom.termsOfService;
123 this.version = copyFrom.version;
124 this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
125 this.license = copyFrom.license == null ? null : copyFrom.license.copy();
126 }
127
128 /**
129 * Make a deep copy of this object.
130 *
131 * @return A deep copy of this object.
132 */
133 public Info copy() {
134 return new Info(this);
135 }
136
137 @Override /* Overridden from OpenApiElement */
138 public <T> T get(String property, Class<T> type) {
139 assertArgNotNull("property", property);
140 return switch (property) {
141 case "title" -> toType(getTitle(), type);
142 case "description" -> toType(getDescription(), type);
143 case "termsOfService" -> toType(getTermsOfService(), type);
144 case "contact" -> toType(getContact(), type);
145 case "license" -> toType(getLicense(), type);
146 case "version" -> toType(getVersion(), type);
147 default -> super.get(property, type);
148 };
149 }
150
151 /**
152 * Bean property getter: <property>contact</property>.
153 *
154 * <p>
155 * The contact information for the exposed API.
156 *
157 * @return The property value, or <jk>null</jk> if it is not set.
158 */
159 public Contact getContact() { return contact; }
160
161 /**
162 * Bean property getter: <property>description</property>.
163 *
164 * <p>
165 * A short description of the application.
166 *
167 * @return The property value, or <jk>null</jk> if it is not set.
168 */
169 public String getDescription() { return description; }
170
171 /**
172 * Bean property getter: <property>license</property>.
173 *
174 * <p>
175 * The license information for the exposed API.
176 *
177 * @return The property value, or <jk>null</jk> if it is not set.
178 */
179 public License getLicense() { return license; }
180
181 /**
182 * Bean property getter: <property>termsOfService</property>.
183 *
184 * <p>
185 * The Terms of Service for the API.
186 *
187 * @return The property value, or <jk>null</jk> if it is not set.
188 */
189 public String getTermsOfService() { return termsOfService; }
190
191 /**
192 * Bean property getter: <property>title</property>.
193 *
194 * <p>
195 * The title of the application.
196 *
197 * @return The property value, or <jk>null</jk> if it is not set.
198 */
199 public String getTitle() { return title; }
200
201 /**
202 * Bean property getter: <property>version</property>.
203 *
204 * <p>
205 * Provides the version of the application API (not to be confused with the specification version).
206 *
207 * @return The property value, or <jk>null</jk> if it is not set.
208 */
209 public String getVersion() { return version; }
210
211 @Override /* Overridden from OpenApiElement */
212 public Set<String> keySet() {
213 // @formatter:off
214 var s = setb(String.class)
215 .addIf(nn(contact), "contact")
216 .addIf(nn(description), "description")
217 .addIf(nn(license), "license")
218 .addIf(nn(termsOfService), "termsOfService")
219 .addIf(nn(title), "title")
220 .addIf(nn(version), "version")
221 .build();
222 // @formatter:on
223 return new MultiSet<>(s, super.keySet());
224 }
225
226 @Override /* Overridden from OpenApiElement */
227 public Info set(String property, Object value) {
228 assertArgNotNull("property", property);
229 return switch (property) {
230 case "contact" -> setContact(toType(value, Contact.class));
231 case "description" -> setDescription(s(value));
232 case "license" -> setLicense(toType(value, License.class));
233 case "termsOfService" -> setTermsOfService(s(value));
234 case "title" -> setTitle(s(value));
235 case "version" -> setVersion(s(value));
236 default -> {
237 super.set(property, value);
238 yield this;
239 }
240 };
241 }
242
243 /**
244 * Bean property setter: <property>contact</property>.
245 *
246 * <p>
247 * The contact information for the exposed API.
248 *
249 * @param value
250 * The new value for this property.
251 * <br>Can be <jk>null</jk> to unset the property.
252 * @return This object
253 */
254 public Info setContact(Contact value) {
255 contact = value;
256 return this;
257 }
258
259 /**
260 * Bean property setter: <property>description</property>.
261 *
262 * <p>
263 * A short description of the application.
264 *
265 * @param value
266 * The new value for this property.
267 * <br>Can be <jk>null</jk> to unset the property.
268 * @return This object
269 */
270 public Info setDescription(String value) {
271 description = value;
272 return this;
273 }
274
275 /**
276 * Bean property setter: <property>license</property>.
277 *
278 * <p>
279 * The license information for the exposed API.
280 *
281 * @param value
282 * The new value for this property.
283 * <br>Can be <jk>null</jk> to unset the property.
284 * @return This object
285 */
286 public Info setLicense(License value) {
287 license = value;
288 return this;
289 }
290
291 /**
292 * Bean property setter: <property>termsOfService</property>.
293 *
294 * <p>
295 * The Terms of Service for the API.
296 *
297 * @param value
298 * The new value for this property.
299 * <br>Can be <jk>null</jk> to unset the property.
300 * @return This object
301 */
302 public Info setTermsOfService(String value) {
303 termsOfService = value;
304 return this;
305 }
306
307 /**
308 * Bean property setter: <property>title</property>.
309 *
310 * <p>
311 * The title of the application.
312 *
313 * @param value
314 * The new value for this property.
315 * <br>Property value is required.
316 * <br>Can be <jk>null</jk> to unset the property.
317 * @return This object
318 */
319 public Info setTitle(String value) {
320 title = value;
321 return this;
322 }
323
324 /**
325 * Bean property setter: <property>version</property>.
326 *
327 * <p>
328 * Provides the version of the application API (not to be confused with the specification version).
329 *
330 * @param value
331 * The new value for this property.
332 * <br>Property value is required.
333 * <br>Can be <jk>null</jk> to unset the property.
334 * @return This object
335 */
336 public Info setVersion(String value) {
337 version = value;
338 return this;
339 }
340
341 @Override /* Overridden from OpenApiElement */
342 public Info strict() {
343 super.strict();
344 return this;
345 }
346
347 @Override /* Overridden from OpenApiElement */
348 public Info strict(Object value) {
349 super.strict(value);
350 return this;
351 }
352 }